C_栈和队列(ADT)-队列的非循环(带头指针)顺序表示和实现
来源:互联网 发布:百姓网发帖软件 编辑:程序博客网 时间:2024/05/22 00:45
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
顺序队列一次性要分配大量保证够用的空间,效率较高,因为是基于数组的,长度也是固定的。可以实现变长,但是一般代价较高。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
出列元素时不移动元素,只改变队头元素的位置
优点:带头指针非循环队列,在出队元素时,只改变头指针的位置,不移动元素,可以简化操作,节约时间
缺点:队列的每个存储空间自始自终只能存储一个队列元素。即使这个队列元素出列后,存储空间浪费较大
队列的定义:
struct SqQueue2{QElemType *base;//初始化的动态分配内存空间int front;//头指针,若队列不空,指向队列的头元素int rear;//尾指针, 若队列不空,指向队列尾元素的下一个位置int queuesize;//当前分配的存储容量(以sizeof(QElemType)为单位) };
基本操作的函数定义:
/*操作结果:构造一个空队列Q*/void InitQueue(SqQueue2 &Q)/*初始条件:队列Q存在*//*操作结果:销毁队列Q,Q不再存在*/void DestroyQueue(SqQueue2 &Q)/*初始条件:队列Q存在*/ /*操作结果:将Q清为空队列*/Status ClearQueue(SqQueue2 &Q)/*初始条件:队列Q存在*//*操作结果:若队列为空队列,则返回TRUE,否则返回FALSE*/Status QueueEmpty(SqQueue2 Q)/*初始条件:队列Q存在*//*操作结果:若队列不为空,则用e返回Q的队头元素,并返回OK,否则返回FALSE*/Status GetHead(SqQueue2 Q,QElemType &e)/*初始条件:队列Q存在*//*操作结果:返回队列的长度*/int QueueLength(SqQueue2 Q)/*初始条件:队列Q存在*//*操作结果:插入元素e为Q的新的队尾元素*/void EnQueue(SqQueue2 &Q,QElemType e)/*初始条件:队列Q存在*//*操作结果:若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR*/Status DeQueue(SqQueue2 &Q,QElemType &e)/*初始条件:队列Q存在*//*操作结果:从队头到队尾依次对队列中每个元素调用函数vi()*/void QueueTraverse(SqQueue2 Q,void(*vi)(QElemType))
下面是函数的实现
构造一个空队列Q
/*操作结果:构造一个空队列Q*/void InitQueue(SqQueue2 &Q){Q.base=(QElemType*)malloc(QUEUE_INIT_SIZE*sizeof(QElemType));if(!Q.base){printf("构造空队列失败!操作退出!\n");exit(0);}else{Q.front=Q.rear=0;Q.queuesize=QUEUE_INIT_SIZE;}}
销毁队列Q
/*初始条件:队列Q存在*//*操作结果:销毁队列Q,Q不再存在*/void DestroyQueue(SqQueue2 &Q){if(Q.base)free(Q.base);Q.base=NULL;Q.front=Q.rear=Q.queuesize=0;}
将Q清为空队列
/*初始条件:队列Q存在*/ /*操作结果:将Q清为空队列*/Status ClearQueue(SqQueue2 &Q){Q.front=Q.rear=0;return OK;}
队队列进行判空
/*初始条件:队列Q存在*//*操作结果:若队列为空队列,则返回TRUE,否则返回FALSE*/Status QueueEmpty(SqQueue2 Q){if(Q.front==Q.rear)//队列为空的标志return TRUE;elsereturn FALSE; }
返回队头元素
/*初始条件:队列Q存在*//*操作结果:若队列不为空,则用e返回Q的队头元素,并返回OK,否则返回FALSE*/Status GetHead(SqQueue2 Q,QElemType &e){if(Q.front==Q.rear)//队列空return ERROR;e=Q.base[Q.front];return OK; }
返回队列长度
/*初始条件:队列Q存在*//*操作结果:返回队列的长度*/int QueueLength(SqQueue2 Q){return (Q.rear-Q.front);}
插入新的队尾元素
/*初始条件:队列Q存在*//*操作结果:插入元素e为Q的新的队尾元素*/void EnQueue(SqQueue2 &Q,QElemType e){if(Q.rear==Q.queuesize){//队列满,增加存储单元 Q.base=(QElemType*)realloc(Q.base,(Q.queuesize+QUEUE_INIT_SIZE)*sizeof(QElemType)); if(!Q.base)//增加单元失败exit(0);}Q.base[Q.rear++]=e; }
删除队列的队头元素
/*初始条件:队列Q存在*//*操作结果:若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR*/Status DeQueue(SqQueue2 &Q,QElemType &e){if(Q.front==Q.rear)//队列空return ERROR;e=Q.base[Q.front++];return OK; }
正序遍历队列
/*初始条件:队列Q存在*//*操作结果:从队头到队尾依次对队列中每个元素调用函数vi()*/void QueueTraverse(SqQueue2 Q,void(*vi)(QElemType)){int i=Q.front;while(i!=Q.rear)vi(Q.base[i++]);printf("\n");}
嗯下面就是在VC中的测试:
#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define QUEUE_INIT_SIZE 10//队列存储空间的初始化分配量#define QUEUE_INCREMENT 2//队列存储空间的分配增量typedef int QElemType;typedef int Status;struct SqQueue2{QElemType *base;//初始化的动态分配内存空间int front;//头指针,若队列不空,指向队列的头元素int rear;//尾指针, 若队列不空,指向队列尾元素的下一个位置int queuesize;//当前分配的存储容量(以sizeof(QElemType)为单位) };void vi(QElemType e){printf("%d \n",e);}void print(QElemType i){printf("%d ",i);}/*操作结果:构造一个空队列Q*/void InitQueue(SqQueue2 &Q){Q.base=(QElemType*)malloc(QUEUE_INIT_SIZE*sizeof(QElemType));if(!Q.base){printf("构造空队列失败!操作退出!\n");exit(0);}else{Q.front=Q.rear=0;Q.queuesize=QUEUE_INIT_SIZE;}}/*初始条件:队列Q存在*//*操作结果:销毁队列Q,Q不再存在*/void DestroyQueue(SqQueue2 &Q){if(Q.base)free(Q.base);Q.base=NULL;Q.front=Q.rear=Q.queuesize=0;}/*初始条件:队列Q存在*/ /*操作结果:将Q清为空队列*/Status ClearQueue(SqQueue2 &Q){Q.front=Q.rear=0;return OK;}/*初始条件:队列Q存在*//*操作结果:若队列为空队列,则返回TRUE,否则返回FALSE*/Status QueueEmpty(SqQueue2 Q){if(Q.front==Q.rear)//队列为空的标志return TRUE;elsereturn FALSE; } /*初始条件:队列Q存在*//*操作结果:若队列不为空,则用e返回Q的队头元素,并返回OK,否则返回FALSE*/Status GetHead(SqQueue2 Q,QElemType &e){if(Q.front==Q.rear)//队列空return ERROR;e=Q.base[Q.front];return OK; } /*初始条件:队列Q存在*//*操作结果:返回队列的长度*/int QueueLength(SqQueue2 Q){return (Q.rear-Q.front);}/*初始条件:队列Q存在*//*操作结果:插入元素e为Q的新的队尾元素*/void EnQueue(SqQueue2 &Q,QElemType e){if(Q.rear==Q.queuesize){//队列满,增加存储单元 Q.base=(QElemType*)realloc(Q.base,(Q.queuesize+QUEUE_INIT_SIZE)*sizeof(QElemType)); if(!Q.base)//增加单元失败exit(0);}Q.base[Q.rear++]=e; }/*初始条件:队列Q存在*//*操作结果:若队列不为空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR*/Status DeQueue(SqQueue2 &Q,QElemType &e){if(Q.front==Q.rear)//队列空return ERROR;e=Q.base[Q.front++];return OK; } /*初始条件:队列Q存在*//*操作结果:从队头到队尾依次对队列中每个元素调用函数vi()*/void QueueTraverse(SqQueue2 Q,void(*vi)(QElemType)){int i=Q.front;while(i!=Q.rear)vi(Q.base[i++]);printf("\n");}int main(){int i;int n;int ch;QElemType k;SqQueue2 Q;InitQueue(Q);printf("成功构造非循环队列Q!\n");printf("请输入队列中初始存在的个数:");scanf("%d",&n);printf("请依次输入数据元素:\n");for(i=1;i<=n;i++){scanf("%d",&k);EnQueue(Q,k);//依次入队k个元素 }printf("****************************\n");printf("1、增加元素\n2、判空队列\n3、队列长度\n");printf("4、队头元素\n5、队头出列\n6、清空队列\n");printf("7、打印队列\n8、销毁队列\n0、退出操作\n"); printf("****************************\n");printf("请选择要进行的操作:");while(scanf("%d",&ch)&&ch!=0){if(ch==1){printf("请输入要进队的元素:");scanf("%d",&k);EnQueue(Q,k);printf("%d元素成功进入队头!\n");}if(ch==2){if(QueueEmpty(Q))printf("这是一个空队列!\n");elseprintf("这不是一个空队列!\n"); }if(ch==3){printf("队列的长度为:%d\n",QueueLength(Q));}if(ch==4){int d;if(GetHead(Q,d))printf("队头元素是%d\n",d);elseprintf("这是一个空队列!\n");}if(ch==5){int d;if(DeQueue(Q,d))printf("队头元素%d成功出列!\n",DeQueue(Q,d));elseprintf("操作失败!\n");}if(ch==6){if(ClearQueue(Q))printf("队列成功清空!\n");}if(ch==7){printf("队列中的元素为:");QueueTraverse(Q,print);}if(ch==8){DestroyQueue(Q);printf("队列成功销毁,操作退出!\n");exit(0);} printf("请选择要进行的操作:");}printf("成功退出操作!\n");return 0;}
阅读全文
0 0
- C_栈和队列(ADT)-队列的非循环(带头指针)顺序表示和实现
- C_栈和队列(ADT)-队列的非循环(无头指针)顺序表示和实现
- C_栈和队列(ADT)-栈的表示和实现
- C_栈和队列(ADT)-队列的链式表示和实现
- 循环队列的顺序表示和实现
- 循环队列的顺序表示和实现
- 循环队列——队列的顺序表示和实现
- 循环队列——队列的顺序表示和实现
- 循环队列 队列的顺序表示和实现
- 循环队列-队列的顺序表示和实现
- 循环队列——队列的顺序表示和实现
- C_线性表(ADT)-顺序表的表示和实现
- [数据结构][适用循环队列和非循环队列]顺序队列的实现。
- 数据结构学习笔记 --- 队列(循环队列-队列的顺序表示和实现)
- 数据结构学习笔记 --- 队列(循环队列-队列的顺序表示和实现)
- 队列的顺序表示形式和实现
- 顺序队列的表示和实现
- 队列的顺序表示和实现
- 求一个数的二进制表示方法(1305 P102)
- Attention在语音识别中的应用(2)
- GotFocus\SetFocus\LostFocus区别
- Unity AndroidStudio和Unity交互
- [转载]Android之Notification的多种用法
- C_栈和队列(ADT)-队列的非循环(带头指针)顺序表示和实现
- 一些看起来还不错的前端界面
- 单点登录的实现方式
- STM32的CAN总线的接收双FIFO使用方法
- matlab绘图使用
- “#if 0/#if 1 ... #endif”的作用
- centos6版本django部署
- UE4 C++初探
- C#之入门总结_文件_1_13