C_栈和队列(ADT)-队列的链式表示和实现
2017-07-19 09:53
330 查看
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first
in first out)线性表。
队列的定义:
构造一个空队列Q:
销毁队列Q,结果使得队列Q不存在:
队列进行判空 :
用e返回队头元素 :
若队列不为空,删除Q的队头元素,并用e返回其值 :
输出队列中的元素 :
嗯下面就是在VC中的实现:
链表队列基于链表的,要动态创建和删除节点,效率较低,但是可以动态增长。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first
in first out)线性表。
队列的定义:
typedef struct QNode{ ElemType data; struct QNode *next; }QNode,*QueuePtr; //定义链表结点中的数据 typedef struct{ QueuePtr front; //队头指针 QueuePtr rear; //队尾指针 }LinkQueue;基本操作的函数原型:
/*操作结果:构造一个空队列Q*/ InitQueue(&Q); /*初始条件:队列Q已存在。*/ /*操作结果:队列Q被销毁,不再存在。*/ DestroyQueue(&Q); /*初始条件:队列Q已存在。*/ /*操作结果:将Q清为空队列。*/ ClearQueue(&Q); /*初始条件:队列Q已存在。*/ /*操作结果:若Q为空队列,则返回TRUE,否则FALSE*/ QueueEmpty(Q); /*初始条件:队列Q已存在。*/ /*操作结果:返回Q的元素个数,即队列的长度。*/ QueueLength(Q); /*初始条件:Q为非空队列*/ /*操作结果:用e返回Q的队头元素。*/ GetHead(Q,&e); /*初始条件:队列Q已存在*/ /*操作结果:插入元素e为Q的新的队尾元素。*/ EnQueue(&Q,e); /*初始条件:Q为非空队列。*/ /*操作结果:删除Q的队头元素,并用e返回其值。*/ DeQueue(&Q,&e); /*初始条件:Q已存在且非空。*/ /*操作结果:从队头到队尾,依次队Q的每个数据元素调用函数visit(),一旦visit()失败,则操作失败。*/ QueueTraverse(Q,visit());
构造一个空队列Q:
Status InitQueue(LinkQueue &q) { q.front=q.rear=(QueuePtr)malloc(sizeof(QNode)); //创建头结点,头指针指向头结点 if(!q.front) //创建失败 { printf("构造队列失败!\n"); return ERROR; } q.front->next=NULL; //头结点下一个指针指向NULL,避免出现野指针 printf("构造队列成功!\n"); return OK; }
销毁队列Q,结果使得队列Q不存在:
Status DestroyQueue(LinkQueue &q) { while(q.front) { q.rear=q.front->next; free(q.front); q.front=q.rear; } q.front=NULL; //避免出现野指针 \ q.rear=NULL; return OK; }清空队列Q,队列Q依旧存在:
Status ClearQueue(LinkQueue &q) { q.front=q.rear=NULL; return OK; }
队列进行判空 :
Status QueueEmpty(LinkQueue q) {//若队列q为空队列,则返回TRUE,否则返回FALSE if(q.front==q.rear) return TRUE; //头指针和尾指针指向同一块内存,队列为空 else return FALSE; }返回队列q中元素个数,即队列的长度:
Status QueueLength(LinkQueue q) {//返回队列q中元素个数,即队列的长度 int count=0; //count用来记录队列中元素的个数 QueuePtr p=q.front; //p指向结点 while(p!=q.rear) //p所指向的结点不是尾结点 { count++; p=p->next; } return count; }
用e返回队头元素 :
Status GetHead(LinkQueue q,int &e) {//用e返回队头元素 QueuePtr p; if(q.front==q.rear) { printf("这是一个空队列!\n"); return ERROR; }else{ p=q.front->next; //此时p指向头结点 e=p->data; //将队头元素的值赋给e return OK; } }插入元素e为队列的队尾元素 :
Status EnQueue(LinkQueue &q,int e) {//插入元素e为队列的队尾元素 QueuePtr p; p=(QueuePtr)malloc(sizeof(QNode));;//动态生成新的结点 if(!p){ printf("新结点动态创建失败!\n"); return ERROR; }else{ p->data=e; //将e的值先赋给新结点 p->next=NULL; //新结点的指针指向空 q.rear->next=p; //原队尾结点的指针域为指向新结点 q.rear=p; //尾指针指向新结点 return OK; } }
若队列不为空,删除Q的队头元素,并用e返回其值 :
Status DeQueue(LinkQueue &q,ElemType &e) {//若队列不为空,删除Q的队头元素,并用e返回其值 QueuePtr p; if(q.front==q.rear) //此时队列为空队列 { printf("此时队列为空!\n"); return ERROR; }else{ p=q.front->next; //p指向队头结点 e=p->data; //队头结点的值赋给e q.front->next=p->next;//头结点指向下一个结点 if(q.rear==p) //如果删除的队尾结点 q.rear=q.front;//修改队尾指针指向头结点 free(p); return OK; } }
输出队列中的元素 :
void PrintQueue(LinkQueue q) {//输出队列中的元素 if(q.front==q.rear) { printf("这是一个空队列!\n"); } q.front=q.front->next; while(q.front!=NULL) { printf("%d ",q.front->data); q.front=q.front->next; } printf("\n"); }
嗯下面就是在VC中的实现:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define LIST_SIZE 100
#define LISTINCREMENT 10
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
typedef int ElemType;
typedef int Status;
typedef struct QNode{ ElemType data; struct QNode *next; }QNode,*QueuePtr; //定义链表结点中的数据 typedef struct{ QueuePtr front; //队头指针 QueuePtr rear; //队尾指针 }LinkQueue;
//构造一个空队列Q
Status InitQueue(LinkQueue &q)
{
q.front=q.rear=(QueuePtr)malloc(sizeof(QNode)); //创建头结点,头指针指向头结点
if(!q.front) //创建失败
{
printf("构造队列失败!\n");
return ERROR;
}
q.front->next=NULL; //头结点下一个指针指向NULL,避免出现野指针
printf("构造队列成功!\n");
return OK;
}
//销毁队列Q,队列Q不存在
Status DestroyQueue(LinkQueue &q) { while(q.front) { q.rear=q.front->next; free(q.front); q.front=q.rear; } q.front=NULL; //避免出现野指针 \ q.rear=NULL; return OK; }
//清空队列Q,队列Q存在
Status ClearQueue(LinkQueue &q) { q.front=q.rear=NULL; return OK; }
//对队列进行判空
Status QueueEmpty(LinkQueue q) {//若队列q为空队列,则返回TRUE,否则返回FALSE if(q.front==q.rear) return TRUE; //头指针和尾指针指向同一块内存,队列为空 else return FALSE; }
Status QueueLength(LinkQueue q) {//返回队列q中元素个数,即队列的长度 int count=0; //count用来记录队列中元素的个数 QueuePtr p=q.front; //p指向结点 while(p!=q.rear) //p所指向的结点不是尾结点 { count++; p=p->next; } return count; }
Status GetHead(LinkQueue q,int &e) {//用e返回队头元素 QueuePtr p; if(q.front==q.rear) { printf("这是一个空队列!\n"); return ERROR; }else{ p=q.front->next; //此时p指向头结点 e=p->data; //将队头元素的值赋给e return OK; } }
Status EnQueue(LinkQueue &q,int e) {//插入元素e为队列的队尾元素 QueuePtr p; p=(QueuePtr)malloc(sizeof(QNode));;//动态生成新的结点 if(!p){ printf("新结点动态创建失败!\n"); return ERROR; }else{ p->data=e; //将e的值先赋给新结点 p->next=NULL; //新结点的指针指向空 q.rear->next=p; //原队尾结点的指针域为指向新结点 q.rear=p; //尾指针指向新结点 return OK; } }
Status DeQueue(LinkQueue &q,ElemType &e) {//若队列不为空,删除Q的队头元素,并用e返回其值 QueuePtr p; if(q.front==q.rear) //此时队列为空队列 { printf("此时队列为空!\n"); return ERROR; }else{ p=q.front->next; //p指向队头结点 e=p->data; //队头结点的值赋给e q.front->next=p->next;//头结点指向下一个结点 if(q.rear==p) //如果删除的队尾结点 q.rear=q.front;//修改队尾指针指向头结点 free(p); return OK; } }
void PrintQueue(LinkQueue q) {//输出队列中的元素 if(q.front==q.rear) { printf("这是一个空队列!\n"); } q.front=q.front->next; while(q.front!=NULL) { printf("%d ",q.front->data); q.front=q.front->next; } printf("\n"); }
int main()
{
int e;
int ch;
ElemType n;
LinkQueue q;
InitQueue(q); //构造一个空队列;
printf("******************************\n");
printf("1、队尾插入元素\n2、队头删除元素\n3、返回列头元素\n");
printf("4、返回队列中元素的个数\n5、队列进行判空\n6、清空队列元素\n");
printf("7、销毁队列\n8、输出队列元素\n9、退出操作\n");
printf("******************************\n");
printf("请选择接下来要进行的操作:");
while(scanf("%d",&ch)&&ch!=9)
{
if(ch==1){
printf(
b881
"请输入队尾插入的元素");
scanf("%d",&e);
if(EnQueue(q,e)){
printf("队尾插入元素%d成功!\n",e);
}else{
printf("操作失败!\n");
}
}
if(ch==2){
if(DeQueue(q,e)){
printf("队头删除元素%d成功!\n",e);
}else{
printf("操作失败");
}
}
if(ch==3){
if(GetHead(q,e)){
printf("队列的头元素是%d\n",e);
}else{
printf("返回队列头元素失败!\n");
}
}
if(ch==4){
printf("队列里面的元素个数有%d\n",QueueLength(q));
}
if(ch==5){
if(QueueEmpty(q))
printf("这是一个空队列!\n");
else
printf("这是一个非空队列!\n");
}
if(ch==6){
if(ClearQueue(q))
printf("队列已经清空!\n");
else
printf("操作失败!");
}
if(ch==7){
if(DestroyQueue(q))
printf("队列已经销毁!\n");
else
printf("操作失败!\n");
}
if(ch==8){
PrintQueue(q);
}
printf("请选择接下来要进行的操作:");
}
printf("退出成功!\n");
return 0;
}
相关文章推荐
- 队列的链式表示和实现
- 队列的链式表示与实现
- 数据结构之队列的链式表示及其实现
- 数据结构-->队列的链式实现 ADT
- 队列的链式表示和实现
- 链队列---队列的链式表示和实现
- 链队列——队列的链式表示与实现
- 链队列——队列的链式表示和实现
- 链队列-队列的链式表示和实现
- 数据结构(C语言版)---第三章栈和队列 3.4.2 队列的链式表示和实现(循环队列)
- 数据结构之队列的链式表示和实现
- 链队列——队列的链式表示和实现
- 队列的链式表示和实现
- 队列的链式表示和实现----循环队列
- C_栈和队列(ADT)-队列的非循环(无头指针)顺序表示和实现
- 队列的链式表示和实现
- 队列在Java类库中的链式表示及实现——LinkedList
- 数据结构(C语言版)---第三章栈和队列 3.4.2 队列的链式表示和实现(单链表)
- 《链队列---队列的链式表示和实现》
- 链式队列ADT实现(C语言)2018.3.14