数据结构5————队的概念和运算

数据结构5 —————队的概念和运算

一. 队的概念

1.定义
  • 栈是一种只允许在一端进行插入,在另一端进行删除的线性表,和栈类似都是一种操作受限的线性表
2. 相关概念
  • 队头:允许进行删除的一端称为队顶
  • 队尾:允许进行插入的一端称为队底
  • 出队:在队头进行删除操作
  • 入队:在队尾进行插入操作
  • 空队:队内没有元素
3. 特点

先进先出。

4.栈的ADT定义
Data
	同线性表。元素具有相同的类型,相邻元素具有前驱和后继关系。

Operation
	InitQueue(*Q):初始化操作,建立一个空队列Q。
	DestroyQueue(*Q):若队列Q存在,則销毀它。
	ClearQueue(*Q):将队列 Q 清空。
	QueueEmpty(Q):若队列Q为空,送回true,否則退回false。
	GetHead(Q, *e):若队列Q存在且非空,用e返因队列Q的队头元素。
	EnQueue(*Q,e):若队列Q存在,插入新元素e到队列Q中并成为队尾元素。 
	DeQueue(*Q, *e):刪除队列Q中队头元素,并用e返回其值。	
	QueueLength(Q):送回队列Q的元素个教。
endADT
5. 栈的存储结构
  • 顺序存储结构(循环队列)
  • 链式存储结构(链栈)
6.图示

二. 链队列

1.结构定义
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0 

typedef int Elemtype;
//节点 
typedef	 struct node{
	Elemtype date;
	struct node *next;
}QNode;

//链队的头尾指针
typedef struct{
	QNode *front;
	QNode *rear;
}LQueue;
2.说明
  • 用链表作为队的存储形式(非线性存储),靠近头结点一端为队头,另一端为队尾,使用两个指针,一个指向队头,一个指向队尾
  • 空栈情况:指向队头的坐标等于指向队尾的坐标。
  • 入队:创建新的节点,并将它链接到队尾,尾指针移动
  • 出队:先判空,如果不是空栈将头结点的下一个节点删除
3.图示

这里写图片描述

4.初始化
//初始化
LQueue *InitLQueue(){
	LQueue *qL;
	QNode *p;
	qL=(LQueue *)malloc(sizeof(LQueue));
	p=(QNode *)malloc(sizeof(QNode));
	p->next=NULL;
	qL->front=qL->rear=p;
	return qL; 
}
5.入队
//入队
int InLQueue(LQueue *qL ,Elemtype x){
	QNode *p;
	p=(QNode *)malloc(sizeof(QNode));
	p->date=x;
	p->next=NULL;
	
	qL->rear->next=p;
	qL->rear=p;
		
	return TRUE; 
} 
6.判断是否为空
//判空队 
int EmptyLQueue(LQueue *qL){
	if(qL->front==qL->rear)
		return TRUE;
	
	return FALSE;
} 
7.出队
//出队
int QutLQueue(LQueue *qL ,Elemtype *x){
	QNode *p;
	if(!EmptyLQueue(qL)){ //栈不空 
	
		p=qL->front->next;
		*x=p->date;
		
		qL->front->next=p->next;//删除
		free(p);
		
		if(qL->front->next ==NULL)
			qL->rear = qL->front;
		return TRUE; 		 
	}
	printf("空队\n"); 
	return FALSE; 
} 

8.链栈的其他方法

可将链表设置为循环链表,只设置尾指针,也可以完成链表的所有操作,具体实现可见我最后代码链接里的代码

三. 循环队列

1.结构定义
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0 
#define MAXSIZE 10
typedef int Elemtype;

typedef struct{
	Elemtype date[MAXSIZE];
	int front,rear; 
}CSeQeue;
2.说明
  • 循环队列是使用数组作为存储形式(线性存储),开始时靠近下标0为队头,另一端为队尾,之后队尾到达数组的末尾后,如果队头不在0处,那么队尾从靠近0的一端重新开始,形成一个环
  • 这个示例代码中,使用的牺牲一个空间来判断队空,还是队满
  • 队空:队尾==队头
  • 队满:队尾+1 == 队头
  • 入栈:
qS->rear=(qS->rear+1)%MAXSIZE;//计算入对后队尾的位置
qS->date[qS->rear]=x;//入队
  • 出栈:
qS->front=(qS->front+1)%MAXSIZE;//计算出队后的队头位置
*x = qS->date[qS->front];//出队
3.图示

这里写图片描述

4.初始化
//初始化
CSeQeue *InitSeQueue(){
	CSeQeue *qS;
	qS=(CSeQeue *)malloc(sizeof(CSeQeue));
	qS->rear=qS->front=MAXSIZE-1;
	return qS;
}
5.入队
//入队
int InSeQueue(CSeQeue *qS ,Elemtype x){
	
	if((qS->rear+1)%MAXSIZE==qS->front){
		printf("队满\n");
		return FALSE;
	}
	qS->rear=(qS->rear+1)%MAXSIZE;
	qS->date[qS->rear]=x;
	return TRUE;
} 
6.判断是否为空
//判空
int EmptySeQueue(CSeQeue *qS){
	
	if(qS->front == qS->rear)
		return TRUE;
	return FALSE;
} 
7.出队
//出队 
int QutSeQueue(CSeQeue *qS ,Elemtype *x){
	if(!EmptySeQueue(qS)){
		qS->front=(qS->front+1)%MAXSIZE;
		*x = qS->date[qS->front];
		return TRUE;
	}
	printf("队空\n");
	return FALSE; 
} 
8.循环队列的其他实现方法

设置一个标志来判断是队空还是队满
不使用队尾指针,改为长度

四. 源码

test2文件夹中

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值