【概述】
链式队列是采取链式存储的队列,其不存在队列满而导致上溢的情况,通常设计为一个带头结点的单链表,其有两个指针,队头指针向队头结点,尾指针指向队尾结点
链式队列的实现类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| template <typename T> struct LNode { T data; LNode<T> *next; }; template <typename T> class LinkQueue { public: LinkQueue(); int getLen(); bool empty(); bool pop(T &elem); bool push(T elem); bool getTop(T &elem); void print(); private: LNode<T> *head; LNode<T> *tail; int len; };
|
【初始化】
链式队列被设计为带头结点的单链表,因此其头指针 head
的初始化与带头结点的单链表相似,只是要注意令尾指针 tail
的指向与 head
相同,并给队长 len
赋 $0$ 值即可
1 2 3 4 5 6 7
| template <typename T> LinkQueue<T>::LinkQueue() { head = (LNode<T> *)malloc(sizeof(LNode<T>)); tail = head; head->next = NULL; len = 0; }
|
【求队长】
由于数据结构中封装了队长 len
,因此在求队长时,直接输出 len
即可
1 2 3 4
| template <typename T> int LinkQueue<T>::getLen() { return len; }
|
【判空】
由于 tail
指向队尾元素的下一位置,即接下来要插入的位置,因此在判空时,只需判断队尾指针与队头指针是否相同即可
1 2 3 4 5 6
| template <typename T> bool LinkQueue<T>::empty() { if (head == tail) return true; return false; }
|
【出队】
在出队时,首先进行下溢判断,再令队长 len-1
,然后将队首结点释放,最后释放结点空间即可,要注意的是,如果要出队的是最后一个结点,要令尾指针 tail
与头指针 head
指向相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| template <typename T> bool LinkQueue<T>::pop(T &elem) { if (empty()) return false; len--; LNode<T> *p = head->next; elem = p->data; head->next = p->next; if (tail == p) tail = head; free(p); return true; }
|
【入队】
在入队时,首先令队长 len+1
,之后为新结点赋值,再连接到队尾
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| template <typename T> bool LinkQueue<T>::push(T elem) { LNode<T> *p = (LNode<T> *)malloc(sizeof(LNode<T>)); if (p == NULL) return false; len++; p->data = elem; p->next = NULL; tail->next = p; tail = p; return true; }
|
【取队头】
在取队首元素时,先进行下溢判断,然后直接取队首指针 head
指向头结点的下一元素的值即可
1 2 3 4 5 6 7
| template <typename T> bool LinkQueue<T>::getTop(T &elem) { if (empty()) return false; elem = head->next->data; return true; }
|
【输出】
在输出时,从队首开始,将队列中所有元素依次出队,进行输出即可
1 2 3 4 5 6 7 8 9
| template <typename T> void LinkQueue<T>::print() { int elem; while (!empty()) { pop(elem); cout << elem << " "; } cout << endl; }
|