链式队列只能尾进头出,为了方便将front指针指向队列的头结点,而队尾指针指向终端结点;
链表初始化:创建一个空链表,并且空链表内包含一个头结点,头结点的后继为空,同时头指针与尾指针同时指向头结点。
链表的入队:新创建一个结点,判断队列是否为空,将队尾的后继指向新结点。同时将新结点作为尾结点。
链表的出队:通过头结点的后继找到第一个节点,将第一个结点的后继赋值给头结点的后继。然后删除free第一个结点。
链表的遍历:遍历时最好通过传值方式,防止在遍历过程中修改原链表。遍历条件是头指针不等于尾指针。
1 #include<iostream> 2 #define Max 50 3 using namespace std; 4 typedef int ElemType; 5 typedef struct QueueNode //链式队列结点的定义 6 { 7 struct QueueNode* next; 8 ElemType data; 9 }QueueNode; 10 11 typedef struct LinkQueue //链式队列的定义 12 { 13 QueueNode* front;//队列头结点指针 14 QueueNode* real;//队列尾结点指针 15 }LinkQueue; 16 17 //队列方法声明 18 19 LinkQueue* CreateLinkQueue(); //创建一个含有头结点的空队列 20 void DestroyLinkQueue(LinkQueue* pqueue); //销毁队列 21 int LengthLinkQueue(LinkQueue* pqueue); //获取队列长度 22 void ClearLinkQueue(LinkQueue* pqueue); //清空队列内元素 23 bool IsEmptyLinkQueue(LinkQueue* pqueue); //检测是否为空队列 24 bool IsFullLinkQueue(LinkQueue* pqueue); //检测是否为满队列 25 LinkQueue* PushLinkQueue(LinkQueue* qstack, ElemType e); //将元素从队列尾入队 26 LinkQueue* PopLinkQueue(LinkQueue* qstack, ElemType* e); //将元素从队列头出队 27 int GetLinkQueue(LinkQueue* pqueue); //获取队列首元素 28 void ShowLinkQueue(LinkQueue pqueue); //遍历队列内元素 29 30 //栈方法实现 31 //创建一个含有头结点的空队列 32 LinkQueue* CreateLinkQueue() 33 { 34 LinkQueue* p = (LinkQueue*)malloc(sizeof(LinkQueue)); //创建空队列 35 if (p == nullptr) 36 exit(-1); 37 p->front = (QueueNode*)malloc(sizeof(QueueNode));// 创建头结点 38 if (p->front == nullptr) 39 exit(-1); 40 p->front->next = nullptr;//创建含头结点的空队列 41 p->real = p->front; 42 return p; 43 } 44 //销毁队列 45 void DestroyLinkQueue(LinkQueue* pqueue) 46 { 47 ClearLinkQueue(pqueue); 48 if (pqueue) 49 free(pqueue); 50 } 51 //清空队列结点 52 void ClearLinkQueue(LinkQueue* pqueue) 53 { 54 55 QueueNode* p = pqueue->front->next; 56 while (p) 57 { 58 pqueue->front->next = p->next; 59 free(p); 60 p = pqueue->front->next; 61 } 62 pqueue->real = pqueue->front; 63 64 } 65 66 int LengthLinkQueue(LinkQueue pqueue) 67 { 68 int num = 0; 69 while (pqueue.front != pqueue.real) 70 { 71 num++; 72 pqueue.front = pqueue.front->next; 73 } 74 return num; 75 } 76 77 //检测是否为空队列 78 bool IsEmptyLinkQueue(LinkQueue* pqueue) 79 { 80 return pqueue->real == pqueue->front ? true:false; 81 } 82 //检测是否为满队列 83 bool IsFullLinkQueue(LinkQueue* pqueue) 84 { 85 // return (pqueue->real+1)% Max == pqueue->front; 86 return true; 87 } 88 //向队列尾部插入元素 89 LinkQueue* PushLinkQueue(LinkQueue* pqueue, ElemType e) 90 { 91 QueueNode* p = (QueueNode*)malloc(sizeof(QueueNode));//申请新结点 92 if (!p)//内存分配失败 93 exit(-1); 94 p->data = e;//给新结点赋值 95 p->next = nullptr; 96 pqueue->real->next = p;//新结点赋值给原尾结点的后继 97 pqueue->real = p;//把当前新结点作为尾结点 98 return pqueue; 99 } 100 //将队列第一个结点出队 101 LinkQueue* PopLinkQueue(LinkQueue* pqueue, ElemType* e) 102 { 103 104 if (IsEmptyLinkQueue(pqueue)) 105 { 106 return nullptr; 107 } 108 else 109 { 110 QueueNode* p = pqueue->front->next;//将删除的队列第一个结点赋值给一个临时指针 111 *e = p->data;//将与删除的值赋值给第一个结点 112 pqueue->front->next = p->next;//原队列的队头后继指向头结点后继 113 if (pqueue->real == p) 114 { 115 pqueue->real = pqueue->front; 116 } 117 free(p);//释放掉弹出结点的空间 118 return pqueue; 119 } 120 } 121 //获取队首元素 122 int GetLinkQueue(LinkQueue* pqueue) 123 { 124 return pqueue->front->next->data; 125 } 126 //遍历栈内元素 127 void ShowLinkQueue(LinkQueue pqueue) 128 { 129 while (pqueue.front != pqueue.real) 130 { 131 cout << pqueue.front->next->data<<" "; 132 pqueue.front = pqueue.front->next; 133 } 134 cout << endl; 135 } 136 int main() { 137 LinkQueue* que,*s; 138 que = CreateLinkQueue(); 139 cout << IsEmptyLinkQueue(que) << endl; 140 s = PushLinkQueue(que, 3); 141 s = PushLinkQueue(que, 4); 142 s = PushLinkQueue(que, 5); 143 s = PushLinkQueue(que, 6); 144 s = PushLinkQueue(que, 7); 145 cout << LengthLinkQueue(*que) << endl; 146 cout << GetLinkQueue(que) << endl; 147 ShowLinkQueue(*que); 148 cout << IsEmptyLinkQueue(que) << endl; 149 int i = 5; 150 int* j = &i; 151 s = PopLinkQueue(que, j); 152 ShowLinkQueue(*que); 153 s = PopLinkQueue(que, j); 154 ShowLinkQueue(*que); 155 ClearLinkQueue(que); 156 ShowLinkQueue(*que); 157 cout << IsEmptyLinkQueue(que) << endl; 158 return 0; 159 160 }