数据结构——链式循环队列

        自己实现了一个链式循环队列(带头结点的),复习巩固队列与循环链表的知识吧。实现函数有:插入、删除、判断是否为空三个方法(链式存储结构就不太在意为满的情况了,因为内存是动态申请的)。其实链式循环队列,本质还是实现循环链表,只是加了队列的头尾指针,然后多了需要判断队列是否为空,而判断是否为空,在删除函数DeleteQ中有一个很关键的地方:

    Position p=Q->Front->Next;      //用p前驱,为了后续释放空间方便
    Q->Front->Next=p->Next;         //修改Front指针的下一个结点
    if(Q->Rear==p)
        Q->Rear=Q->Front;               //当删除到最后一个元素时,由于,我实现的是带头结点的队列,队列的头指针Front始终在head这个头结点上,在删除操作过程中,Rear指针一直在Front指针前面(如图),所以,在删除最后一个元素之后,想要确保队列能达到空,必须将Rear指针也回到head结点上,这样,判断是否为空才能实现

数据结构——链式循环队列_第1张图片

         代码如下:

/*
	JunWei-Huang 
	循环队列的链式存储实现
	想要达到循环,本质还是实现“链表的循环”即可,只是在循环链表上,加了两个头尾指针,然后“插入”、“删除”操作受限而已 
	最后修改时间:2023-11-10 
*/ 
#include
#include
#define MAX 10 				//链式的有没有最大值无所谓,可以不用管大小,内存是可以任意的
#define ERROR -9999
typedef int ElementType;
typedef struct Node * PtrToNode;
struct Node{
	ElementType Data;
	PtrToNode Next;
};
typedef PtrToNode Position;

typedef struct QNode* PtrToQNode;
struct QNode{
	Position Front,Rear;
};
typedef PtrToQNode Queue; 
Queue CreateQueue(int MaxSize);
bool IsFull(Queue Q);
bool AddQ(Queue Q,ElementType X);
bool IsEmpty(Queue Q);
ElementType DeleteQ(Queue Q);
		/* 1.带头结点的链式队列实现*/ 
int main(){
		//通过创建一个队列,然后输入一段数据,输出一段数据来实现各个操作集 
		int qSize,i,data;
		Queue qs=CreateQueue(MAX);
		printf("请输入你想要入队的元素个数qSize:");
		scanf("%d",&qSize);
		for(i=1;i<=qSize;i++){//创建队列(入队操作) 
			printf("请输入第%d个队列元素data:",i);
			scanf("%d",&data);
			AddQ(qs,data); 

		}
		//手动控制出队数
		ElementType d;
		int n;
		printf("请输入你这次想要出队的个数n:");
		scanf("%d",&n);
		for(i=1;i<=n;i++){//打印队列(出队操作)
				d= DeleteQ(qs);
				if(d==ERROR){
					printf("队列已空\n");
					break;
			}
			printf("第%d个队列元素是:%d\n",i,d);
	
		}
		//程序结束了,把所有开辟出来的结点释放掉 
		while(DeleteQ(qs)!=ERROR);
		return 0;
}
Queue CreateQueue(int MaxSize){//创建一个空的“带头结点的”循环链式队列 
	Position head=(Position)malloc(sizeof(struct Node));//创建一个空的结点作为头结点 
	head->Next=head;							//头结点Next指向自己,这样,循环链表的初始化就完成了! 
	Queue q=(Queue)malloc(sizeof(struct QNode));//创建好头尾指针 
	//循环链表已经完成了,接下来,只需要把头尾指针指向即可
	q->Front=head;
	q->Front=q->Rear;						//让头尾指针指向头结点
//	q->MaxSize=MaxSize;  						链式实现不用设置最大值 
	return q;
	
}
bool IsFull(Queue Q){//链式循环队列就不必实现判断满的方法了 
	
} 
bool AddQ(Queue Q,ElementType X){//入队操作 
//	if(IsFull(Q))
//	return false;
	//不管三七二十一,先把要入队的结点创建好 
	Position s=(Position)malloc(sizeof(struct Node));
	s->Data=X;
	//入队,连在尾结点后面 
	s->Next=Q->Rear->Next;
	Q->Rear->Next=s;		//把链表连起来,再移动Rear指针 			
	Q->Rear=s;			 
	return true;
}
bool IsEmpty(Queue Q){//判断队列是否为空 
	//循环链式队列判断为空与顺序队列的一样(即个两指针都指向head结点,而head结点自己指向自己),就是: 
	return (Q->Rear==Q->Front);
}
ElementType DeleteQ(Queue Q){//出队操作 
	if(IsEmpty(Q)) 
		return ERROR;
	Position p=Q->Front->Next;
	Q->Front->Next=p->Next;
	if(Q->Rear==p)
		Q->Rear=Q->Front;		//这句话非常重要,因为出队,到了最后一个元素,要让尾指针Rear回到头指针的位置,不然出队了永远不会判断对队列是否为空 
	ElementType x=p->Data;
	free(p);
	return x;
		
	 
}

你可能感兴趣的:(数据结构,数据结构,链表)