链队列的综合操作(详解、演示)C语言实现
2016-04-21 18:56
513 查看
队列的简介
和栈相反,队列(queue)是一种先进先出(简称FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。举个我们生活中最最常见的例子:银行排队(不管什么排队),当我们去银行办理业务的时候,我们要按照先来后到的规矩,先来的人先处理后面的人候着,先来的人处理完了之后先走…..
根据上面的例子大家应该可以很清楚的理解队列是什么了,再来看个示意图
和线性表类似,队列也有两种存储表示
用链表表示的队列称为链队列、还有一个循环队列在下一篇博客讲。一个链队列显然需要两个分别指向队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。这里,和线性表的单链表一样,为了操作方便起见,我们也给链队列添加一个头结点,并令头结点指针指向头结点,由此。空的链队列的判决条件为头指针和尾指针均指向头结点。
链队列的操作即是单链表的插入和删除操作的特殊情况。只需修改头尾指针即可,下面的程序实现和演示了,队列的构造、销毁、清空队列、销毁队列、判断队列是否为空、获得队列长度、获得队头、入队列、出队列、显示队列等功能。
/********************************************************* - Copyright (C): 2016 - File name : queue.c - Author : - Zhaoxinan - - Date : 2016年04月21日 星期四 15时34分59秒 - Description : 单链队列的存储 * *******************************************************/ #include <stdio.h> #include <stdlib.h> #define TRUE 1 #define FALSE -1 #define OK 1 #define ERROR -1 #define OVERFLOW -2 /* ---- 单链队列----队列的链式存储结构 ---- */ typedef struct Qnode { int date; struct Qnode *next; }QNode,* QueuePtr; typedef struct { QueuePtr head; //队头指针 QueuePtr tail; //队尾指针 }LinkQueue; /* ---- 基本操作函数 ---- */ /* ---- 构造一个空队列 ---- */ int InitQueue(LinkQueue *Q) { Q->head = Q->tail = (QueuePtr)malloc(sizeof(QNode)); if (Q->head == NULL) { exit(OVERFLOW); } Q->tail->next = NULL; return OK; } /* ---- 销毁队列Q,Q不再存在 ---- */ int DestoryQueue(LinkQueue *Q) { //head->node1->node2->node3->tail; // tail // head->node2 while(Q->head) { Q->tail = Q->head->next; free(Q->head); Q->head = Q->tail; } Q->head = Q->tail = NULL; return OK; } /* ---- 将Q清空空队列 ---- */ int ClearQueue(LinkQueue *Q) { QueuePtr temp; Q->tail = Q->head->next; while(Q->tail) { temp = Q->tail->next; //指向下一个待释放的单元 free(Q->tail); Q->tail = temp; } Q->tail = Q->head; //修改队尾指针 return OK; } /* ---- 若队列Q为空队列,返回TRUE,否则返回FALSE ---- */ int QueueEmpty(LinkQueue Q) { if (Q.head == Q.tail && Q.head != NULL) { return TRUE; } else { return FALSE; } } /* ---- 返回Q的元素个数,即队列的长度 ---- */ int QueueLength(LinkQueue Q) { if (Q.head == NULL) { return 0; } QueuePtr temp; int count = 0; temp = Q.head->next; while(temp != NULL) { temp = temp->next; ++count; } return count; } /* ---- 显示当前队列的值从队头到队尾 ---- */ void show_queue(LinkQueue Q) { QueuePtr temp; temp = Q.head->next; printf(" 当前队列从头到尾:"); while(temp != NULL) { printf("%d ", temp->date); temp = temp->next; } printf("\n"); } /* ---- 若队列不空,则用e返回Q的队头元素,并返回OK, 否则返回ERROR ---- */ int GetHead(LinkQueue Q, int *e) { if (QueueEmpty(Q) == TRUE) { return ERROR; } *e = Q.head->next->date; return OK; } /* ---- 插入元素e为Q的新的对尾元素 ---- */ int EnQueue(LinkQueue *Q, int e) { if (Q->head == NULL || Q->tail == NULL) { return ERROR; } QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode)); if (!ptr) { exit(OVERFLOW); } ptr->date = e; ptr->next = NULL; Q->tail->next = ptr; Q->tail = ptr; return OK; } /* ---- 若队列不空,则删除Q的队头元素,并用e返回其值,并返回OK,否则返回ERROR ---- */ int DeQueue(LinkQueue *Q, int *e) { if (Q->head == Q->tail) { return ERROR; } /* ptr为临时变量 */ QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode)); //head->node1->node2->tail; // ptr // head->node2->tail ptr = Q->head->next; *e = ptr->date; Q->head->next = ptr->next; if (Q->tail == ptr) { Q->head = Q->tail; } free(ptr); return OK; } int main() { int i; //循环变量 int count; //计数变量 int outque; //出队元素值 LinkQueue Q; /* 初始化队列 */ InitQueue(&Q); /* 插入10个元素 */ printf("________________入队10个元素________________\n\n"); for (i = 0; i < 10; i++) { /* 入队 */ EnQueue(&Q, i); /* 获得当前队列中元素个数 */ count = QueueLength(Q); printf("%2d 入队_当前队列中元素个数:%2d",i, count); show_queue(Q); } printf("________________出队5个元素________________\n\n"); for (i = 0; i < 5; i++) { /* 出队 */ DeQueue(&Q, &outque); /* 获得当前队列中元素个数 */ count = QueueLength(Q); printf("%2d 出队_当前队列中元素个数:%2d", outque, count); show_queue(Q); } /* 获得当前队头值 */ GetHead(Q, &outque); printf("\n当前队头为:%d\n", outque); printf("________________清空队列_________________\n\n"); ClearQueue(&Q); count = QueueLength(Q); printf("当前队列中元素个数:%2d", count); show_queue(Q); printf("________________销毁队列_________________\n\n"); DestoryQueue(&Q); count = QueueLength(Q); printf("当前队列中元素个数:%2d\n\n", count); return 0; }
程序的运行结果
相关文章推荐
- 快速排序的递归形式与非递归形式(C++版)
- 栈的应用--括号匹配的检验(C++)
- 【转载】c++ API 在屏幕上(或窗口中)的(x,y)坐标绘制一个点
- C语言宏定义和宏定义函数
- C++中的类的继承和组合
- C++ 中 cin cin.get() cin.getline()的用法
- 倒三角形代码C++
- c语言产生随机数的方法
- C++对象和类
- C语言中结构体指针的定义和引用
- C++练习题
- C++中测数组的长度
- C语言里的指针
- 数字图像处理,相位相关图像配准算法的C++实现
- makefile编译C++程序 gcc/g++区别
- c++远征之启航篇
- C/C++常考面试题(2)
- C语言文件输入、输出 I/O(十二)
- c++中常见的类型转换int,string,float
- 详解C++中实现继承string类的MyString类的步骤