数据结构之链队列

来源:互联网 发布:程序员转行产品经理 编辑:程序博客网 时间:2024/06/05 07:36

一.引入

        链队列是在单链表的基础上做了简单的修改,为了使空队列和非空队列的操作一致,链队列也加上头结点。根据队列的先进先出特性,为了操作上的方便,设置队头指针指向链队列的头结点,队尾指针指向终端结点。


二.算法设计

LinkedQueue.h

#ifndef SRC_LINKEDQUEUE_H_#define SRC_LINKEDQUEUE_H_/* * 结点: * data:数据域,存储数据元素 * next:指针域,存储该结点的后继结点的地址 */template <class T>struct Node{    T data;    Node<T> *next;};template <class T>class LinkedQueue {public:LinkedQueue();//无参构造器LinkedQueue(T array[],int length);//有参构造器virtual ~LinkedQueue();//析构函数int getLength();//取当前队的长度    void enqueue(T value);//入队    T dequeue();//出队    T getHead();//取队头元素    void getAll();//遍历队的全部元素    bool isEmpty();//判断是否队空private:    Node<T> *front;//队头指针,指向头结点(注意:不是队头,而是队头的前一个结点,该结点的 next 域存储的是队头的位置)    Node<T> *rear;//队尾指针,指向队尾    int length;//当前队的长度};#endif

三.详细设计(C++)

LinkedQueue.cpp

#include "LinkedQueue.h"#include <iostream>using namespace std;/* * 无参构造器: * 1.创建一个头结点 head ,申请空间 * 2.把头结点 head 的 next 置为 NULL * 3.队头指针 front 指向头结点 head * 4.队尾指针 rear 指向头结点 head * 5.当前队的长度置为 0 */template <class T>LinkedQueue<T>::LinkedQueue(){    Node<T> *head = new Node<T>;    head->next = NULL;    front = head;    rear = head;    length = 0;}/* * 有参构造器: * 1.创建一个头结点 head ,申请空间 * 2.把头结点 head 的 next 置为 NULL * 3.队头指针 front 指向头结点 head * 4.队尾指针 rear 指向头结点 head * 5.当前队的长度置为 0 * 6.创建一个结点 node ,置为 NULL * 7.循环: *   ①.为结点 node 申请空间 *   ②.把数组的值存储在结点 node 的 data 域中 *   ③.把结点 node 的 next 域置为 NULL *   ④.把原队尾结点的 next 置为结点 node 的地址,即原队尾结点与结点 node 相连 *   ⑤.队尾指针 rear 指向结点 node ,即结点 node 成为队尾结点 * 8.记录当前队的长度 */template <class T>LinkedQueue<T>::LinkedQueue(T array[],int length){    Node<T> *head = new Node<T>;    head->next = NULL;    front = head;    rear = head;    Node<T> *node = NULL;    for(int i = 0;i < length;i++){        node = new Node<T>;        node->data = array[i];        node->next = NULL;        rear->next = node;        rear = node;    }    this->length = length;}/* * 析构函数: * 1.创建一个结点 deleteNode ,置为 NULL * 2.循环: *   ①.结点 deleteNode 指向队头 *   ②.队头指针 front 指向队头的下一个结点 *   ③.判断结点 deleteNode 是否是队尾,若是则队尾指针 rear 和队头指针 front 指向同一个结点,即头结点 *   ④.删除结点 deleteNode ,即队头 *   ⑤.当前队的长度减一 * 3.删除头结点 */template <class T>LinkedQueue<T>::~LinkedQueue(){Node<T> *deleteNode = NULL;while(!isEmpty()){deleteNode = front->next;front->next = deleteNode->next;if(deleteNode->next == NULL){rear = front;}delete deleteNode;length--;}delete front;}/* * 取当前队的长度: * 返回当前队的长度 */template <class T>int LinkedQueue<T>::getLength(){return length;}/* * 入队: * 1.创建一个结点 enNode ,申请空间 * 2.把 value 存储在结点 enNode 的 data 域中 * 3.结点 enNode 的 data 域置为 NULL * 4.原队尾结点的 next 域置为结点 enNode 的地址,即原队尾结点与结点 enNode 相连 * 5.队尾指针 rear 指向结点 enNode ,即结点 enNode 成为新队尾 * 6.当前队的长度加一 */template <class T>void LinkedQueue<T>::enqueue(T value){    Node<T> *enNode = new Node<T>;    enNode->data = value;    enNode->next = NULL;    rear->next = enNode;    rear = enNode;    length++;}/* * 出队: * 1.判断是否队空,若是返回 -1,否则 * 2.创建一个结点 head ,其指向队头 * 3.定义一个变量 headValue ,其记录队头结点存储的元素 * 4.队头指针 front 的 next 域置为原队头的下一个结点的地址,即头结点与新队头相连 * 5.判断原队头是否也是队尾,即当前队是否只剩下一个结点(不包括头结点),若是则队尾指针 rear 和队头指针 front 指向同一个结点,即头结点 * 6.删除原队头 * 7.当前队的长度减一 * 8.返回原队头存储的元素 headValue */template <class T>T LinkedQueue<T>::dequeue(){if(isEmpty()){cout<<"队空!"<<endl;return -1;}Node<T> *head = front->next;T headValue = head->data;front->next = head->next;if(head->next == NULL){rear = front;}delete head;length--;return headValue;}/* * 取队头元素: * 1.判断是否队空,若是返回 -1,否则 * 2.返回队头结点存储的元素 * 注意:不删除队头结点 */template <class T>T LinkedQueue<T>::getHead(){if(isEmpty()){cout<<"队空!"<<endl;return -1;}return front->next->data;}/* * 遍历队的全部元素: * 1.判断是否队空,若是返回,否则 * 2.创建一个结点 p ,其指向队头 * 3.循环:当未到达队尾时 *   ①.输出结点 p 指向的结点存储的元素 *   ②.结点 p 指向下一个结点 * 4.输出队尾结点存储的元素 */template <class T>void LinkedQueue<T>::getAll(){if(isEmpty()){cout<<"队空!"<<endl;return;}Node<T> *p = front->next;while(p->next != NULL){cout<<p->data<<" ";p = p->next;}cout<<p->data<<endl;}/* * 判断是否队空: * 若队头结点 front 和队尾结点 rear 指向同一个结点,即头结点,则返回 true ,否则返回 false */template <class T>bool LinkedQueue<T>::isEmpty(){return front == rear ? true : false;}


四.测试

TestLinkedQueue.cpp

#include "LinkedQueue.h"#include "LinkedQueue.cpp"#include <iostream>using namespace std;int main(int argc, char **argv) {int arr[] = {0,1,2,3,4};cout<<"创建对象:0、1、2、3、4 依次入队 "<<endl;LinkedQueue<int> linkedQueue(arr,5);cout<<"遍历队内的元素:";linkedQueue.getAll();cout<<"当前队的长度:";cout<<linkedQueue.getLength()<<endl;cout<<"当前的队头元素:"<<linkedQueue.getHead()<<endl;cout<<endl;while(!linkedQueue.isEmpty()){cout<<linkedQueue.dequeue()<<"出队!"<<endl;cout<<"遍历队内的元素:";linkedQueue.getAll();cout<<"当前队的长度:";cout<<linkedQueue.getLength()<<endl;cout<<"当前的队头元素:"<<linkedQueue.getHead()<<endl;cout<<endl;}cout<<endl;for(int i = 0;i < 10;i++){cout<<i<<"入队!"<<endl;linkedQueue.enqueue(i);}cout<<"遍历队内的元素:";linkedQueue.getAll();cout<<"当前队的长度:";cout<<linkedQueue.getLength()<<endl;cout<<"当前的队头元素:"<<linkedQueue.getHead()<<endl;cout<<endl;cout<<"销毁队!"<<endl;linkedQueue.~LinkedQueue();return 0;}

五.运行结果




原创粉丝点击