数据结构 队列
队列
(1)队列是一种先进先出的线性表
(2)只能从队头进行删除,从队尾进行插入
(一)链队列
(1)需要一个指向头结点的头指针和一个指向尾结点的尾指针
(2)通常为了操作的方便起见,都会给链队添加一个头结点,头结点不存数据。
(3)有头结点的链队列判空的条件是头指针和尾指针都指向头结点
链队列的实现代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #define STACK_INIT_SIZE 100 4 #define STACKINCREMENT 10 5 typedef int Status; 6 #define OK 1 7 #define ERROR 0 8 typedef struct QNode 9 { 10 char data; 11 struct QNode *next; 12 }QNode, *QueuePtr; 13 14 typedef struct { 15 QueuePtr front; 16 QueuePtr rear; 17 }LinkQueue; 18 19 //创建队列 20 void InitQueue(LinkQueue *Q) 21 { /* 构造一个空队列Q */ 22 (*Q).front = (*Q).rear = (QueuePtr)malloc(sizeof(QNode)); 23 if (!(*Q).front) exit(ERROR); 24 (*Q).front->next = NULL; 25 } 26 27 //入队 28 void EnQueue(LinkQueue *Q, char e) 29 { /* 插入元素e为Q的新的队尾元素 */ 30 QueuePtr p = (QueuePtr)malloc(sizeof(QNode)); 31 if (!p) exit(ERROR); /* 存储分配失败 */ 32 p->data = e; p->next = NULL; 33 (*Q).rear->next = p; (*Q).rear = p; 34 } 35 36 //出队 37 void DeQueue(LinkQueue *Q, char *e) 38 { /* 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR */ 39 QueuePtr p; 40 if ((*Q).front == (*Q).rear) exit(ERROR); /* 空队列退出 */ 41 p = (*Q).front->next; 42 *e = p->data; 43 (*Q).front->next = p->next; 44 if ((*Q).rear == p) (*Q).rear = (*Q).front; 45 free(p); 46 } 47 48 //输入队列内容 49 void printfQueue(LinkQueue Q) 50 { 51 QueuePtr p; 52 p = Q.front->next; 53 while (p) 54 { 55 printf("%c ", p->data); 56 p = p->next; 57 } 58 printf("\n"); 59 } 60 61 int main() 62 { 63 LinkQueue Q; 64 char e; 65 InitQueue(&Q); 66 67 int num, i; 68 char a,c; 69 printf("输入入队元素个数:\n"); 70 scanf("%d", &num); 71 c = getchar(); 72 printf("输入入队元素:\n"); 73 74 for (i = 0; i < num; i++){ 75 scanf("%c", &a); 76 c = getchar(); 77 EnQueue(&Q, a); 78 } 79 printf("队里的元素为:"); 80 printfQueue(Q); 81 printf("出队顺序为:"); 82 for (i = 0; i < num; i++){ 83 DeQueue(&Q, &e); 84 printf("%c ",e); 85 } 86 system("pause"); 87 return 0; 88 }
循环队列
采用一组地址连续的存储单元依次存放从队头到队尾的元素,并且附加两个指针front和rear分别指向队头和队尾。
(1)无法使用Q.front = Q.rear 来判别队列是“空”还是“满”,如下图,空队列和存满的队列都有Q.front = Q.rear
可以采用少用一个元素空间的存储方式,约定以队列头指针在队列尾指针的下一位置上作为队列呈“满”状态的标志。如图
判断队列是否为“满” 语句:(Q.rear + 1) % MAX_QSIZE == Q.front (MAX_QSIZE表示队列容量)
实现代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef int Status; 4 #define OK 1 5 #define ERROR 0 6 #define MAX_QSIZE 10 7 typedef struct 8 { 9 char *base; /* 初始化的动态分配存储空间 */ 10 int front; /* 头指针,若队列不空,指向队列头元素 */ 11 int rear; /* 尾指针,若队列不空,指向队列尾元素的下一个位置 */ 12 }SqQueue; 13 14 //创建循环队列 15 void InitQueue(SqQueue *Q) 16 { /* 构造一个空队列Q */ 17 (*Q).base = (char *)malloc(MAX_QSIZE*sizeof(int)); 18 if (!(*Q).base) /* 存储分配失败 */ 19 exit(ERROR); 20 (*Q).front = (*Q).rear = 0; 21 } 22 23 //入队 24 void EnQueue(SqQueue *Q, int e) 25 { /* 插入元素e为Q的新的队尾元素 */ 26 if (((*Q).rear + 1) % MAX_QSIZE == (*Q).front) /* 队列满 */ 27 exit(ERROR);; 28 (*Q).base[(*Q).rear] = e; 29 (*Q).rear = ((*Q).rear + 1) % MAX_QSIZE; 30 } 31 //出队 32 void DeQueue(SqQueue *Q, char *e) 33 { /* 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR */ 34 if ((*Q).front == (*Q).rear) /* 队列空 */ 35 exit(ERROR); 36 *e = (*Q).base[(*Q).front]; 37 (*Q).front = ((*Q).front + 1) % MAX_QSIZE; 38 } 39 40 //输出队列内容 41 void printfQueue(SqQueue Q) 42 { /* 从队头到队尾依次对队列Q中每个元素输出 */ 43 int i; 44 i = Q.front; 45 while (i != Q.rear) 46 { 47 printf("%3c", Q.base[i]); 48 i = (i + 1) % MAX_QSIZE; 49 } 50 printf("\n"); 51 } 52 53 void main() 54 { 55 int i,num; 56 char a,d,c; 57 SqQueue Q; 58 InitQueue(&Q); 59 printf("输入入队元素个数:\n"); 60 scanf("%d", &num); 61 c = getchar(); 62 printf("输入入队元素:\n"); 63 for (i = 0; i < num; i++){ 64 scanf("%c", &a); 65 c = getchar(); 66 EnQueue(&Q, a); 67 } 68 printf("队里的元素为:"); 69 printfQueue(Q); 70 printf("出队顺序为:"); 71 for (i = 0; i < num; i++){ 72 DeQueue(&Q, &d); 73 printf("%c ", d); 74 } 75 76 system("pause"); 77 }