队列Queue定义与操作

#include<stdio.h>
#define MaxSize 100
#define OK 1
#define ERROR 0

typedef int Status;//表示返回的状态值 
typedef int ElemType;




/*
1、队列可分为“循环队列”和“栈队列”
   循环队列 :通过将顺序的内存地址看做首位相连的地址,来实现队列的增删,缺点是队列有最大的固定大小
   栈队列 :则是通过链表来实现,更为灵活
2、队列是FIFO(FIRST IN FIRST OUT)机制,
3、还有“双端队列”,即两端都可以增删,可以实现队列和堆栈的功能,但并不常用





*/








//链队列数据结点的结构体定义
typedef struct Node
{
	ElemType data;
	struct Node *next;
}Node;



//链队列的类型定义
typedef struct 
{
	Node *front;//存队列头指针,指向头结点,头结点一般不存储数据!!
	Node *rear;//存队列尾指针
	int length;//队列长度
}Queue;



//初始化队列
//O(1)
Status InitialQueue(Queue &Q)
{
	Q.rear=Q.front=(Node*)malloc(sizeof(Node));//为头结点分配一个内存
    if(!Q.front)
	{
		exit(OVERFLOW);
	}
	Q.front->next=NULL;//为了最后的结点指针指向空
	Q.length=0;//初始长度
	return OK;
}


//摧毁队列(即将队列的结点以及头结点的内存释放,而Clear不释放头结点)
//O(1)
Status DestroyQueue(Queue &Q)
{
	while(!Q.front)//若为NULL则退出
	{
		Q.rear=Q.front->next;//用rear作为移动指针
		free(Q.front);//从头结点开始释放内存
		Q.front=Q.rear;//或取下一个结点
	}
    return OK;
}


//进队
//O(1)
Status EnQueue(Queue &Q,ElemType e)
{
	Node *p=(Node*)malloc(sizeof(Node));
	if(!p)
	{
		exit(OVERFLOW);
	}
	Q.rear->next=p;
	Q.rear=p;
	Q.rear->data=e;//赋值给新结点
	Q.rear->next=Null;//指空表示队尾
	return OK;
}


//出队
//O(1)
Status DeQueue(Queue &Q,ElemType &e)
{
	Node *p=Q.front->next;//p为要删去的结点
	if(Q.front==Q.rear)
	{
		return ERROR;//空队列不可出队
	}
	Q.front->next=p->next;//重指向队头
	e=p->data;
	if(Q.rear==p)
	{
		Q.rear=Q.front;//此时应该都为NULL
	}
	free(p);
	return OK;
}




//--------------------------------------------------------------------



//循环队列的结构体定义
//通过数组(顺序存储结构)实现
//循环队列中rear应该走在front前面,因为rear是添加数据,因此向前增长
//!!该例中需空出一个数据内存空间用于判别队列是空还是满(即满的时候rear和front不重合)
//!!!!通过%Q.size实现指针的“循环”
typedef struct 
{
	ElemType *base;//申请内存
	int rear;
	int front;
	int size;//队列最大容量(本设计中不可改变)
}Queue;


//初始化循环队列
//O(1)
Status InitialQueue(Queue &Q)
{
	Q.size=MAXSIZE;
	Q.base=(ElemType *)malloc(Q.size*sizeof(ElemType));
	if(!Q.base)
	{
		exit(OVERFLOW);
	}
	Q.front=0;
	Q.rear=0;
	return OK;
}


//获取队列长度
//O(1)
int GetLength(Queue &Q)
{
	if(Q.rear>=Q.front)
	{
		return (Q.rear-Q.front);
	}
	else
	{
		return (Q.size-(Q.front-Q.rear));
	}
	//也可以用  return (Q.size+Q.rear-Q.front)%Q.size;   直接代替
	
}




//进队
//O(1)
Status EnQueue(Queue &Q,ElemType e)
{
	if(GetLength(Q)==Q.size-1)//或者 Q.front==(Q.rear+1)%Q.size;
	{
		return ERROR;  //表明队列已满,不能进队
	}
	Q.base[Q.rear]=e;//添加数据
	if(Q.rear==Q.size-1)
	{
		Q.rear=0;
	}
	else
	{
		Q.rear++;
	}
	//上面可改为 Q.rear=(Q.rear+1)%Q.size;
	return OK;
}



//出队,并将数据传到e
//O(1)
Status DeQueue(Queue &Q,ElemType &e)
{
	if(Q.front==Q.rear)//如果队为空
	{
		return ERROR;
	}
	e=Q.base[Q.front]//返回值,同时没有必要对出队的数据进行清零,不是指针没有必要
	Q.front=(Q.front+1)%Q.size;//指针向前走一步
    return OK;
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值