数据结构 3-2-1 队列的链式存储实现

一、概念

队列也是一种受限的线性表,只允许一端插入另一段输出,就像其名字一样,队列具有先入先出的特点,这是由于其受限的特点所决定的。用链式结构实现队列,称为链队列,实际上是一个带有队头指针和队尾指针的单链表,其中头指针指向队头节点,尾指针指向队尾节点(单链表的最后一个元素)
数据结构 3-2-1 队列的链式存储实现_第1张图片数据结构 3-2-1 队列的链式存储实现_第2张图片

二、定义

队列的链式实现,和单链表很相似,头结点可有可无,最好加上头结点,加上后操作起来更加简便。再加头结点的情况下,初始化时让队头指针和队尾指针都指向头结点来表示队列为空。

struct QNode{
	struct QNode *next;
	int data;
};
struct QNode q;
struct QNode *front,*rear;

三、代码实现

主要功能不多,重要的在于增删节点。删除节点只能在头部进行,所以需要修改队头指针,初始化时我们让队头指针指向了头结点,所以要删除的节点实际上是头结点的下一个节点。除此之外,删除时还要特别注意,当即将要被删除的节点就是最后一个节点时,如果我们直接删除,会连带着队尾指针一起删除,这是我们所不希望的,所以需要加一个特殊判断,当即将被删除的节点就是队尾指针所指的节点时,让对位指针再次指回头结点,此时正好队首指针队尾指针指向一起,队列回归空状态。

int pop()
{
	if(isEmpty())
		return -1;
	struct QNode *temp=front->next;
	front->next=temp->next;
	int num=temp->data;
	if(temp==rear)
		front=rear;
	free(temp);
	return num;
}

增加节点时,只能在队尾操作,我们需要做的就是修改队尾指针,和线性实现不同的是链表实现队尾指针指向的位置一定是存放有元素的,所以我们只需要按照链表增加节点的方法增加即可。

void insert(int num)
{
	struct QNode *temp;
	temp=(QNode*)malloc(sizeof(struct QNode));
	temp->data=num;
	temp->next=NULL;
	rear->next=temp;
	rear=temp;
}

除此之外代码并没有什么值得强调的地方,完整代码如下:

#include
using namespace std;
struct QNode{
	struct QNode *next;
	int data;
};
struct QNode q;
struct QNode *front,*rear;
void init()
{
	front=rear=(QNode*)malloc(sizeof(struct QNode));
	front->next=NULL;
}
bool isEmpty()
{
	if(front==rear)
		return true;
	else
		return false;
}
void insert(int num)
{
	struct QNode *temp;
	temp=(QNode*)malloc(sizeof(struct QNode));
	temp->data=num;
	temp->next=NULL;
	rear->next=temp;
	rear=temp;
}
void insertmode()
{
	int num;
	printf("Input the number you want to insert:");
	scanf("%d",&num);
	insert(num);
}
int pop()
{
	if(isEmpty())
		return -1;
	struct QNode *temp=front->next;
	front->next=temp->next;
	int num=temp->data;
	if(temp==rear)
		front=rear;
	free(temp);
	return num;
}
void popmode()
{
	int num=pop();
	if(num==-1)
		printf("The queue is empty!\n");
	else
		printf("%d has been deleted from the queue!\n",num);
}
void getfront()
{
	if(!isEmpty())
		printf("The first number in the queue is %d\n",front->next->data);
	else
		printf("The queue is empty!\n");
}
void print()
{
	while(!isEmpty())
	{
		getfront();
		pop();
	}
	printf("\n");
}
int main()
{
	int n,choice=-1;
	init();
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		int num;
		scanf("%d",&num);
		insert(num);
	}
	while(choice!=0)
	{
		printf("1-Pop\n");
		printf("2-Insert\n");
		printf("3-getFront\n");
		printf("4-Show\n");
		printf("0-Exit\n");
		printf("Choice the function you want:");
		scanf("%d",&choice);
		switch(choice){
			case 1:popmode();break;
			case 2:insertmode();break;
			case 3:getfront();break;
			case 4:print();break;
			case 0:break;
			default:printf("input error!\n");break;
		}		
	}	
	return 0;
 } 

四、优缺点分析

队列由于其本身就是一个受限的线性表,所以性质上很多都和线性表一致,在链式实现的情况下,最优之处在于内存的自由性,不会出现内存溢出的现象,也没有顺序实现那样需要不断判断队列是不是满了这样的问题。另外当题目需要使用多个队列多个栈的情况时,也最好使用链式队列,这样就不会出现内存分配不合理的问题了。

你可能感兴趣的:(笔记总结,数据结构)