分类
静态队列-用数组实现
链式队列-用链表实现
一般情况下真正实用的顺序队列是循环队列
队列的具体应用:
所有和时间有关的操作都有队列的影子
顺序循环队列
静态队列-用数组实现
#include <stdio.h>
#include <stdlib.h>
#define QueueSize 100
typedef int DataType;
typedef struct
{
DataType data[QueueSize];
int front, rear;
}CirQueue;
void InitQueue(CirQueue *Q);//置空队列
int QueueEmpty(CirQueue *Q);//判队空
int QueueFull(CirQueue *Q);//判队满
void EnQueue(CirQueue *Q, DataType x);//入队列
DataType GetFront(CirQueue *Q);//取对头元素
DataType DeQueue(CirQueue *Q);//出队列
int QueueLength(CirQueue *Q);//队列长度
void main()
{
CirQueue Q;
int i = 0;
InitQueue(&Q);//置空队列
for (i = 0; i < 10; i++)
{
EnQueue(&Q, i);//入队列
}
printf("%d
", QueueLength(&Q));//队列长度
while (!QueueEmpty(&Q))//判队空
{
printf("%d ", DeQueue(&Q));//出队列
}
}
void InitQueue(CirQueue *Q)//置空队列
{
Q->front = Q->rear = 0;
}
int QueueEmpty(CirQueue *Q)//判队空
{
return Q->rear == Q->front;
}
int QueueFull(CirQueue *Q)//判队满
{
return (Q->rear + 1) % QueueSize == Q->front;
}
void EnQueue(CirQueue *Q, DataType x)//入队列
{
if (QueueFull(Q))
{
printf("queue overflow
");
}
else
{
Q->data[Q->rear] = x;
Q->rear = (Q->rear + 1) % QueueSize;//循环意义下的加1
}
}
DataType GetFront(CirQueue *Q)//取对头元素
{
if (QueueEmpty(Q))
{
printf("queue empty
");
exit(0);//出错退出处理
}
else
{
return Q->data[Q->front];//返回队头元素值
}
}
DataType DeQueue(CirQueue *Q)//出队列
{
if (QueueEmpty(Q))
{
printf("queue empty
");
exit(0);//出错退出处理
}
else
{
DataType x = Q->data[Q->front];//保存待删除元素值
Q->front = (Q->front + 1) % QueueSize;//头指针加1
return x;//返回队头元素值
}
}
int QueueLength(CirQueue *Q)//队列长度
{
return (QueueSize + (Q->rear) - (Q->front)) % QueueSize;
}
动态数组实现队列
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define QueueSize 6 5 typedef int DataType;//假设数据为int 6 7 struct queue 8 { 9 DataType * base;//数组 10 int front, rear; 11 }; 12 13 typedef struct queue CirQueue; 14 15 void InitQueue(CirQueue * Q);//置空队列 16 int QueueEmpty(CirQueue * Q);//判队空 17 int QueueFull(CirQueue * Q);//判队满 18 void EnQueue(CirQueue * Q, DataType x);//入队列 19 DataType GetFront(CirQueue * Q);//取队头元素 20 DataType DeQueue(CirQueue * Q);//出队列 21 22 void TraverseQueue(CirQueue * Q);//遍历队列 23 24 void main() 25 { 26 CirQueue Q; 27 28 InitQueue(&Q);//置空队列 29 30 EnQueue(&Q, 1);//入队列 31 EnQueue(&Q, 2); 32 EnQueue(&Q, 3); 33 EnQueue(&Q, 4); 34 EnQueue(&Q, 5); 35 36 TraverseQueue(&Q);//遍历队列 37 38 printf("出队列的元素是%d ", DeQueue(&Q));//出队列 39 printf("出队列的元素是%d ", DeQueue(&Q)); 40 printf("出队列的元素是%d ", DeQueue(&Q)); 41 printf("出队列的元素是%d ", DeQueue(&Q)); 42 printf("出队列的元素是%d ", DeQueue(&Q)); 43 printf("出队列的元素是%d ", DeQueue(&Q)); 44 45 system("pause"); 46 } 47 48 void InitQueue(CirQueue * Q)//置空队列 49 { 50 Q->base = (DataType *)malloc(sizeof(DataType)*QueueSize); 51 Q->front = Q->rear = 0; 52 } 53 54 int QueueEmpty(CirQueue * Q)//判队空 55 { 56 return Q->front == Q->rear; 57 } 58 59 int QueueFull(CirQueue * Q)//判队满 60 { 61 return (Q->front + 1) % QueueSize == Q->front; 62 } 63 64 void EnQueue(CirQueue * Q, DataType x)//入队列 65 { 66 if (QueueFull(Q)) 67 { 68 printf("Queue overflow "); 69 } 70 else 71 { 72 Q->base[Q->rear] = x; 73 Q->rear = (Q->rear + 1) % QueueSize;//循环意义下的加1 74 } 75 } 76 77 DataType GetFront(CirQueue * Q)//取队头元素 78 { 79 if (QueueEmpty(Q)) 80 { 81 printf("Queue empty "); 82 exit(0);//出错退出处理 83 } 84 else 85 { 86 return Q->base[Q->front];//返回队头元素值 87 } 88 } 89 90 DataType DeQueue(CirQueue * Q)//出队列 91 { 92 DataType x; 93 if (QueueEmpty(Q)) 94 { 95 printf("Queue empty "); 96 exit(0);//出错退出处理 97 } 98 else 99 { 100 x = Q->base[Q->front];//保存待删除元素值 101 Q->front = (Q->front + 1) % QueueSize;//头指针加1 102 return x;//返回队头元素值 103 } 104 } 105 106 void TraverseQueue(CirQueue * Q)//遍历队列 107 { 108 int i = Q->front; 109 110 while (i != Q->rear) 111 { 112 printf("%d ", Q->base[i]); 113 i = (i + 1) % QueueSize; 114 } 115 printf(" "); 116 }
链式队列-用链表实现
创建一个链队列,实现优先队列
链队列比一般队列的好处,没有范围限制。
1 头文件Queue.h
2 源文件main.c
3 源文件Queue.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 struct queue
5 {
6 int num;
7 int high;//优先级
8 struct queue *pNext;//存储下一个结点的地址
9 };
10
11 typedef struct queue QUEUDE;//简化队列
12
13 QUEUDE *init(QUEUDE *queueA);//初始化
14 QUEUDE *EnQueue(QUEUDE *queueA, int num, int high);//顺序入队
15 QUEUDE *DeQuedu(QUEUDE *queueA, QUEUDE *pout);//顺序出队
16 QUEUDE *freeall(QUEUDE *queueA);//清空
17 QUEUDE *insertEnQuedu(QUEUDE *queueA, int num, int high);//队列插入,采用插入排序,不要用冒泡排序,原因:优先级相同,也可能会交换
18 void printall(QUEUDE *queueA);//打印所有数据,递归
2 源文件main.c
1 #define _CRT_SECURE_NO_WARNINGS
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include "Queue.h"
6
7 main()
8 {
9 QUEUDE *phead = NULL;//创建头结点
10 phead = init(phead);//初始化
11
12 phead = insertEnQuedu(phead, 1, 3);
13 printall(phead);//打印所有数据,递归
14 printf("
");
15
16 phead = insertEnQuedu(phead, 2, 12);
17 printall(phead);//打印所有数据,递归
18 printf("
");
19
20 phead = insertEnQuedu(phead, 3, 3);
21 printall(phead);//打印所有数据,递归
22 printf("
");
23
24 phead = insertEnQuedu(phead, 4, 14);
25 printall(phead);//打印所有数据,递归
26 printf("
");
27
28 phead = insertEnQuedu(phead, 5, 5);
29 printall(phead);//打印所有数据,递归
30 printf("
");
31
32 phead = insertEnQuedu(phead, 6, 16);
33 printall(phead);//打印所有数据,递归
34 printf("
");
35
36 phead = insertEnQuedu(phead, 7, 0);
37 printall(phead);//打印所有数据,递归
38 printf("
");
39
40 phead = insertEnQuedu(phead, 8, 0);
41 printall(phead);//打印所有数据,递归
42 printf("
");
43
44 phead = insertEnQuedu(phead, 9, 1);
45 printall(phead);//打印所有数据,递归
46 printf("
");
47
48 phead = insertEnQuedu(phead, 10, 0);
49 printall(phead);//打印所有数据,递归
50 printf("
");
51
52 phead = insertEnQuedu(phead, 11, 16);
53 printall(phead);//打印所有数据,递归
54 printf("
");
55
56 phead = insertEnQuedu(phead, 111, 19);
57 printall(phead);//打印所有数据,递归
58 printf("
");
59
60 //while (phead != NULL)//出队
61 //{
62 // QUEUDE *ptemp = (QUEUDE *)malloc(sizeof(QUEUDE));
63 // phead = DeQuedu(phead, ptemp);
64 // printf("出队一次
");
65 // printall(phead);//打印所有数据,递归
66 // printf("出队的是%d,%d
", ptemp->num, ptemp->high);
67 //}
68
69 system("pause");
70 }
3 源文件Queue.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "Queue.h"
4
5 QUEUDE *init(QUEUDE *queueA)//初始化
6 {
7 return NULL;
8 }
9
10 QUEUDE *EnQueue(QUEUDE *queueA, int num, int high)//顺序入队
11 {
12 QUEUDE *pnewnode = (QUEUDE *)malloc(sizeof(QUEUDE));//分配内存
13 pnewnode->num = num;
14 pnewnode->high = high;
15 pnewnode->pNext = NULL;
16
17 if (queueA == NULL)//链表为空
18 {
19 queueA = pnewnode;
20 return queueA;
21 }
22 else
23 {
24 QUEUDE *p = queueA;//头结点
25 while (p->pNext != NULL)//确定要插入的位置
26 {
27 p = p->pNext;
28 }
29 p->pNext = pnewnode;//插入
30
31 return queueA;
32 }
33 }
34
35 QUEUDE *DeQuedu(QUEUDE *queueA, QUEUDE *pout)//顺序出队
36 {
37 if (queueA == NULL)
38 {
39 return NULL;
40 }
41 else
42 {
43 pout->num = queueA->num;
44 pout->high = queueA->high;
45 QUEUDE *ptemp = queueA;//记录要删除的地址
46 queueA = queueA->pNext;//跳过queueA
47 free(ptemp);
48 return queueA;
49 }
50 }
51
52 QUEUDE *freeall(QUEUDE *queueA)//清空,与栈一样
53 {
54
55 }
56
57 QUEUDE *insertEnQuedu(QUEUDE *queueA, int num, int high)//队列插入,采用插入排序,不要用冒泡排序,原因:优先级相同,也可能会交换
58 {
59 //实现从大到小插入
60 QUEUDE *pnewnode = (QUEUDE *)malloc(sizeof(QUEUDE));//分配内存
61 pnewnode->num = num;
62 pnewnode->high = high;
63
64 if (queueA == NULL)//原队列为空
65 {
66 pnewnode->pNext = NULL;
67 queueA = pnewnode;
68 return queueA;
69 }
70 else
71 {
72 if (pnewnode->high > queueA->high)//头部插入1/3
73 {
74 pnewnode->pNext = queueA;
75 queueA = pnewnode;//指向这个结点
76 return queueA;
77 }
78 else
79 {
80 QUEUDE *p = queueA;//头结点
81 while (p->pNext != NULL)
82 {
83 p = p->pNext;//p循环到尾部
84 }
85 if (pnewnode->high <= p->high)//尾部插入2/3
86 {
87 p->pNext = pnewnode;
88 pnewnode->pNext = NULL;
89 return queueA;
90 }
91 else//中间插入3/3
92 {
93 QUEUDE *p1, *p2;
94 p1 = p2 = NULL;//避免野指针
95 p1 = queueA;//头结点
96 while (p1->pNext != NULL)
97 {
98 p2 = p1->pNext;
99 if (p1->pNext >= pnewnode->high && p2->high <= pnewnode->high)
100 {
101 pnewnode->pNext = p2;
102 p1->pNext = pnewnode;//插入
103 break;
104 }
105 p1 = p1->pNext;
106 }
107 return queueA;
108 }
109 }
110 }
111 }
112
113 void printall(QUEUDE *queueA)//打印所有数据,递归
114 {
115 if (queueA == NULL)
116 {
117 return;
118 }
119 else
120 {
121 printf("%d,%d,%x,%x
", queueA->num, queueA->high, queueA, queueA->pNext);
122 printall(queueA->pNext);//进入下一个
123 }
124 }
