数据结构与算法——队列(链式存储)
队列的链式存储结构,其实就是线性表的单链表,只不过它只是尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端节点。
1 typedef int DataType; //队列中元素类型 2 typedef struct _QNode //结点结构 3 { 4 DataType data; 5 struct _QNode* next; 6 }QNode; 7 8 typedef QNode* QueuePtr; //结点结构指针 9 10 typedef struct Queue 11 { 12 int length; //队列的长度 13 QueuePtr front; //队头指针 14 QueuePtr rear; //队尾指针 15 }LinkQueue;
链式队列操作图示
空队列时,front 和 rear 都指向空。
完整实现代码:
1 #include <stdio.h> 2 #include <assert.h> 3 #include <Windows.h> 4 #include <iostream> 5 #include <iomanip> 6 7 using namespace std; 8 9 #define MaxSize 5 //队列的最大容量 10 typedef int DataType; //队列中元素类型 11 12 typedef struct _QNode //结点结构 13 { 14 DataType data; 15 struct _QNode* next; 16 }QNode; 17 18 typedef QNode* QueuePtr; //结点结构指针 19 20 typedef struct Queue 21 { 22 int length; //队列的长度 23 QueuePtr front; //队头指针 24 QueuePtr rear; //队尾指针 25 }LinkQueue; 26 27 //队列初始化,将队列初始化为空队列 28 void InitQueue(LinkQueue* LQ) 29 { 30 if (!LQ) return; 31 LQ->length = 0; 32 LQ->front = LQ->rear = NULL; //把对头和队尾指针同时置0 33 } 34 35 //判断队列为空 36 int IsEmpty(LinkQueue* LQ) 37 { 38 if (!LQ) return 0; 39 if (LQ->front == NULL) 40 { 41 return 1; 42 } return 0; 43 } 44 45 //判断队列是否为满 46 int IsFull(LinkQueue* LQ) 47 { 48 if (!LQ) return 0; 49 if (LQ->length == MaxSize) 50 { 51 return 1; 52 } return 0; 53 } 54 55 //入队,将元素data插入到队列LQ中 56 int EnterQueue(LinkQueue* LQ, DataType data) 57 { 58 if (!LQ) return 0; 59 if (IsFull(LQ)) 60 { 61 cout << "无法插入元素 " << data << ", 队列已满!" << endl; 62 return 0; 63 } 64 65 QNode* qNode = new QNode; 66 qNode->data = data; 67 qNode->next = NULL; 68 69 if (IsEmpty(LQ)) //空队列 70 { 71 LQ->front = LQ->rear = qNode; 72 } 73 else 74 { 75 LQ->rear->next = qNode; //在队尾插入节点qNode 76 LQ->rear = qNode; //队尾指向新插入的节点 77 } 78 LQ->length++; 79 return 1; 80 } 81 82 //出队,将队列中队头的元素出队,其后的第一个元素成为新的队首 83 int DeleteQueue(LinkQueue* LQ, DataType* data) 84 { 85 QNode* tmp = NULL; 86 if (!LQ || IsEmpty(LQ)) 87 { 88 cout << "队列为空!" << endl; 89 return 0; 90 } 91 92 if (!data) return 0; 93 tmp = LQ->front; 94 LQ->front = tmp->next; 95 96 if (!LQ->front) LQ->rear = NULL; //如果对头出列后不存在其他元素,则rear节点也要置空 97 98 * data = tmp->data; 99 LQ->length--; 100 delete tmp; 101 return 1; 102 } 103 //打印队列中的各元素 104 void PrintQueue(LinkQueue* LQ) 105 { 106 QueuePtr tmp; 107 if (!LQ) return; 108 if (LQ->front == NULL) 109 { 110 cout << "队列为空!"; 111 return; 112 } 113 tmp = LQ->front; 114 while (tmp) 115 { 116 cout << setw(4) << tmp->data; 117 tmp = tmp->next; 118 } 119 cout << endl; 120 } 121 122 //获取队首元素,不出队 123 int GetHead(LinkQueue* LQ, DataType* data) 124 { 125 if (!LQ || IsEmpty(LQ)) 126 { 127 cout << "队列为空!" << endl; 128 return 0; 129 } if (!data) return 0; 130 *data = LQ->front->data; 131 return 1; 132 } 133 134 //清空队列 135 void ClearQueue(LinkQueue* LQ) 136 { 137 if (!LQ) return; 138 while (LQ->front) 139 { 140 QueuePtr tmp = LQ->front->next; 141 delete LQ->front; 142 LQ->front = tmp; 143 } 144 LQ->front = LQ->rear = NULL; 145 LQ->length = 0; 146 } 147 148 //获取队列中元素的个数 149 int getLength(LinkQueue* LQ) 150 { 151 if (!LQ) return 0; 152 return LQ->length; 153 } 154 155 int main() 156 { 157 LinkQueue* LQ = new LinkQueue; 158 DataType data = -1; 159 160 //初始化队列 161 InitQueue(LQ); 162 163 //入队 164 for (int i = 0; i < 7; i++) 165 { 166 EnterQueue(LQ, i); 167 } 168 169 //打印队列中的元素 170 printf("队列中的元素(总共%d 个):", getLength(LQ)); 171 PrintQueue(LQ); 172 cout << endl; 173 174 //出队 175 for(int i=0; i<10; i++) 176 { 177 if(DeleteQueue(LQ, &data)) 178 { 179 cout<<"出队的元素是:"<<data<<endl; 180 } 181 else 182 { 183 cout << "出队失败!" << endl; 184 } 185 } 186 187 //打印队列中的元素 188 printf("出队一个元素后,队列中剩下的元素[%d]:", getLength(LQ)); 189 PrintQueue(LQ); 190 cout << endl; 191 ClearQueue(LQ); 192 cout << "清空队列!\n"; 193 PrintQueue(LQ); 194 //清理资源 delete LQ; 195 system("pause"); 196 197 return 0; 198 }
================================================================================================================