「数据结构」线性表(C语言):队列的链式表示和顺序表示

前言

  • 关于假溢出循环队列
    队列的特性是先进先出,后入后出(FIFO),我们在进行入队列和出队列操作时,在队头进行删除元素,在队尾插入元素;假设我们定义一个空间大小MAXSIZE为5的队列
    队列的顺序表示
    当队头元素a出列时,队列空间中就会出现一个空单元,但是如果再来新的元素却无法入队列,因为e后面没有空单元了,队列未溢出却无法入队,这种现象叫假溢出
    假溢出
    循环队列的出现就是为了解决假溢出问题,循环队列的最后一个单元的后继单元为第一个单元。
    循环队列
    循环队列溢出的条件为:(rear + 1) % MAXSIZE = front

队列的部分ADT

  • InitQueue():初始化一个空队列
  • EnterQueue():入队列
  • DeleteQueue():出队列
  • CreateQueue():建立一个队列
  • DisposeQueue():销毁一个队列
  • IsFull():判断是否为溢出
  • IsEmpty():判断是否为空队列

链队列

链队列的入队和出队操作不涉及到队列的溢出情况,这里就没有IsFull操作,只有当设备的内存溢出是队列才会溢出。

存储结构

链队列

全部代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct QueueNode
{
	int data;	//数据域
	struct QueueNode * next;	//指针域
}LinkQueueNode;
typedef struct
{
	LinkQueueNode * front;
	LinkQueueNode * rear;
}LinkQueue;

//初始化队列,即置空队列
void InitQueue(LinkQueue* Q)
{
	Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
	if(Q->front == NULL)
		printf("初始化失败!!\n");
	else
	{
		Q->front->next = NULL;
		Q->rear = Q->front;
		printf("初始化成功!!\n");
	}
}

//判断是否为空队列
bool IsEmpty(LinkQueue* Q)
{
	if(Q->front == Q->rear)		return true;
	else		return false;
}

//入队列
void EnterQueue(LinkQueue* Q,int x)
{
	LinkQueueNode* NewNode;
	NewNode = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
	if(NewNode == NULL)
		printf("队列溢出!!\n");
	else
	{
		NewNode->data = x;
		NewNode->next = NULL;
		Q->rear->next = NewNode;
		Q->rear = NewNode;
		printf("入队成功!!\n");
	}
}

//出队列
void DeleteQueue(LinkQueue* Q)
{
	if(IsEmpty(Q))
		printf("队列为空,无法进行出队列操作!!\n");
	else
	{
		int x;
		LinkQueueNode * Node;
		Node = Q->front->next;
		Q->front->next = Node->next;
		if(Q->rear == Node)
			Q->rear = Q->front;
		x = Node->data;
		free(Node);
		printf("队列元素%d出队成功!!\n",x);
	}
}

//打印队列
void PrintQueue(LinkQueue* Q)
{
	LinkQueueNode * head;
	head = Q->front;
	if(IsEmpty(Q))
		printf("队列为空,无法打印!!\n");
	else
	{
		printf("打印结果:");
		while(head->next != NULL)
		{
			head = head->next;
			printf("%d\t",head->data);
		}
		printf("\n打印成功!!\n");
	}
}

//创建队列
void CreateQueue(LinkQueue* Q)
{
	//1.初始化一个队列

	InitQueue(Q);

	//2.循环入队

	int x;	//入队元素
	char c;	//结束标志
	while(1)
	{
		scanf("%d",&x);
		EnterQueue(Q, x);
		c = getchar();
		if(c == '\n')
			break;
	}	

	//3.打印队列

	PrintQueue(Q);

	//4.创建成功

	printf("创建成功!!\n\n");
}

//销毁队列
void DisposeQueue(LinkQueue* Q)
{
	while(Q->front != Q->rear)
		DeleteQueue(Q);
	printf("队列销毁成功!!\n");
}

int main()
{
	//测试
	LinkQueue L;
	CreateQueue(&L);
	EnterQueue(&L,5);
	PrintQueue(&L);
	DeleteQueue(&L);
	PrintQueue(&L);
	DisposeQueue(&L);
	return 0;
}

队列的顺序表示

队列的顺序表示就是通过数组来存储队列,但是会出现假溢出现象,所以我们直接用循环队列来实现队列的顺序存储

全部代码

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 30
typedef struct
{
	int element[MAXSIZE];
	int front;
	int rear;
}SeqQueue;

//初始化队列
void InitQueue(SeqQueue* Q)
{
	Q->front = Q->rear = 0;
}

//判断是否溢出
bool IsFull(SeqQueue* Q)
{
	if((Q->rear+1) % MAXSIZE == Q->front)
		return true;
	else
		return false;
}

//判断队列是否为空
bool IsEmpty(SeqQueue* Q)
{
	if(Q->rear == Q->front)
		return true;
	else
		return false;
}

//入队操作
void EnterQueue(SeqQueue* Q, int x)
{
	if(IsFull(Q))
		printf("队列已满,无法入队!!\n\n");
	else
	{
		Q->element[Q->rear] = x;
		Q->rear = (Q->rear+1) % MAXSIZE;
		printf("%d入队成功!!\n",x);
	}
}

//出队操作
void DeleteQueue(SeqQueue* Q)
{
	if(IsEmpty(Q))
		printf("队列为空,出队失败!!\n");
	else
	{
		printf("%d出队!\n",Q->element[Q->front]);
		Q->front = (Q->front+1) % MAXSIZE;
	}
}

//创建队列
SeqQueue* CreateQueue()
{
	SeqQueue* Q;
	Q = (SeqQueue*)malloc(sizeof(SeqQueue));
	InitQueue(Q);
	int x;	//入队元素
	char c;	//结束标志
	while(1)
	{
		scanf("%d",&x);
		EnterQueue(Q, x);
		c = getchar();
		if(c == '\n')
			break;
	}
	printf("创建成功\n");
	return Q;
}

//销毁队列
void DisposeQueue(SeqQueue* Q)
{
	free(Q);
	Q = NULL;
}

//打印队列
void PrintQueue(SeqQueue* Q)
{
	if(IsEmpty(Q))
		printf("队列为空,打印失败!!\n");
	else
	{
		printf("打印结果:");
		int i = Q->front;
		while(1)
		{
			printf("%d\t",Q->element[i]);
			i = (i + 1) % MAXSIZE;
			if(i == Q->rear)
				break;
		}
		printf("\n打印成功!!\n");
	}
}
int main()
{
	SeqQueue* L;
	L = CreateQueue();
	PrintQueue(L);
	EnterQueue(L,5);
	PrintQueue(L);
	DeleteQueue(L);
	PrintQueue(L);
	DisposeQueue(L);
	return 0;
}
发布了20 篇原创文章 · 获赞 75 · 访问量 6903

猜你喜欢

转载自blog.csdn.net/weixin_42089228/article/details/103994349