数据结构—5.队列的应用
一、双端队列
-
什么是双端队列呢?
首先,它还是一个循环队列(环形队列),但是它的特点就是队列头head也可以入队列,队列尾tail也可以出队列。所以它就有了新的应用,我们先画图研究下上述情况下它的区别在哪儿?
第一种情况下:head - 1,但是如图所示,下标为0的存储空间的上一个是SIZE,而不是0 - 1 = -1,如何表示呢?head =(head - 1 + SIZE)% SIZE;然后,将要存储的元素入队列。
第二种情况下:先执行出队列,然后更新head =(head + 1)% SIZE;
第三种情况下:tail = (tail - 1 + SIZE)% SIZE;
第四种情况下:tail = (tail + 1) % SIZE;
-
代码实现
/* * @name 双端队列 * @Date 2021年11月27日 * @Author 机器人工程师sgk */ #include <stdio.h> #include <string.h> #define SIZE 512 char queue[SIZE]; int head, tail = 0;//队列的两个关键要素,头和尾。 void head_enqueue(char c); char head_dequeue(void); void tail_enqueue(char c); char head_dequeue(void); int is_empty(void); int is_full(void); int is_palindrom(char *pt); int main(void) { return 0; } /* * @name head_enqueue * @brief 入队列。 * @param char 型数据 * @retval None */ void head_enqueue(char c) { tail = (tail - 1 + SIZE) % SIZE; queue[tail] = c; } /* * @name head_dequeue * @brief 出队列 * @param None * @retval char 型数据。 */ char head_dequeue(void) { char ch; ch = queue[head]; head = (head + 1) % SIZE; return ch;//出队列,队列的头不断增加。 } /* * @name tail_enqueue * @brief 队列尾入队列。 * @param char 型数据 * @retval None */ void tail_enqueue(char c) { queue[tail] = c;//不断有元素入队列,表现形式是队列的尾在不断增加。 tail = (tail + 1) % SIZE; } /* * @name tail_dequeue * @brief 队列尾出队列 * @param None * @retval char 型数据。 */ char tail_dequeue(void) { char ch; tail = (tail - 1 + SIZE) % SIZE; ch = queue[tail]; return ch;//出队列,队列的头不断增加。 } /* * @name is_empty * @brief 判断队列是否为空。 * @param None * @retval int型数据类型 */ int is_empty(void) { return head == tail; } /* * @name is_full * @brief 判断队列是否存满了。 * @param None * @retval int型数据类型 */ int is_full(void) { return ((tail + 1) % SIZE) == head; }
-
双端队列的应用
还是判断回文数,回文数比如:abcba、abccba等。
这里的思路是:
/* * @name 双端队列 * @Date 2021年11月27日 * @Author 机器人工程师sgk */ #include <stdio.h> #include <string.h> #define SIZE 512 char queue[SIZE]; int head, tail = 0;//队列的两个关键要素,头和尾。 void head_enqueue(char c); char head_dequeue(void); void tail_enqueue(char c); char head_dequeue(void); int is_empty(void); int is_full(void); int is_palindrom(char *pt); int main(void) { char str[100]; printf("Please enter a palindrom: \n"); gets(str); if(is_palindrom(str)) printf("str is a palindrom.\n"); else printf("str is not a palindrom.\n"); return 0; } /* * @name head_enqueue * @brief 入队列。 * @param char 型数据 * @retval None */ void head_enqueue(char c) { tail = (tail - 1 + SIZE) % SIZE; queue[tail] = c; } /* * @name head_dequeue * @brief 出队列 * @param None * @retval char 型数据。 */ char head_dequeue(void) { char ch; ch = queue[head]; head = (head + 1) % SIZE; return ch;//出队列,队列的头不断增加。 } /* * @name tail_enqueue * @brief 队列尾入队列。 * @param char 型数据 * @retval None */ void tail_enqueue(char c) { queue[tail] = c;//不断有元素入队列,表现形式是队列的尾在不断增加。 tail = (tail + 1) % SIZE; } /* * @name tail_dequeue * @brief 队列尾出队列 * @param None * @retval char 型数据。 */ char tail_dequeue(void) { char ch; tail = (tail - 1 + SIZE) % SIZE; ch = queue[tail]; return ch;//出队列,队列的头不断增加。 } /* * @name is_empty * @brief 判断队列是否为空。 * @param None * @retval int型数据类型 */ int is_empty(void) { return head == tail; } /* * @name is_full * @brief 判断队列是否存满了。 * @param None * @retval int型数据类型 */ int is_full(void) { return ((tail + 1) % SIZE) == head; } /* * @name is_palindrom * @brief 判断是否为回文? * @param str首地址 * @retval int型数据类型 */ int is_palindrom(char *pt) { int i = 0; char temp1, temp2; for(i = 0; i < strlen(pt); i++) if(!is_full()) tail_enqueue(pt[i]); while(!is_empty()) { temp1 = head_dequeue();//当队列不为空时,从队列头取出一个数据,并保存在临时变量temp1里。 if(!is_empty()) temp2 = tail_dequeue();//再判断一次队列是否为空,取出队列尾的一个数据,并保存在临时变量temp2里。 else break;//如果为空的话,退出while(); if(temp1 == temp2)//比较两个数据是否相同。 continue; else return 0; } return 1; }
运行结果:
Please enter a palindrom: 123321 str is a palindrom Please enter a palindrom: 123456 str is not a palindrom Please enter a palindrom: abcba str is a palindrom