数据结构---队列

(一)基本概念

      队列是一种特殊的线性表(先进先出),特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。  先进先出的数据结构

     队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。 队列就像一个两端相通的水管,只允许一端插入,另一端取出,先放入管中的球先从管中拿出,如图所示。

 


 

 (二)顺序队列

队列结点类型:

typedef char Data;
typedef struct
{
   Data  data[MaxSize];
   int front ,rear;
}SqQueue;//声明顺序队列类型

顺序队列: 因为存在假溢出现象,故不怎么用;而通常采用一种解决队列“假溢出”问题的方法:环形队列去代替

     顺序队列中,如果没有按照取余数的方式入队,就会在数组的最后,出现数组溢出(rear==MaxSize-1),此时,即使数组前面有空间,也不能正确入队,形成假溢出。

  //假溢出时:sq.rear == maxsize-1,但队列中实际容量并未达到最大容量的现象; 

 环形队列:

初始化:

//初始化队列
SqQueue*   InitQueue()
{
	SqQueue *q = (SqQueue*)malloc(sizeof(SqQueue));
	assert(q);
	q->front = q->rear = 0;
	return q;
}  

  入队:

//进队
void enQueue(SqQueue* q,Data e)
{
	if ((q->rear + 1) % MaxSize == q->front)
	{
		printf("队列已满,插入不了!");
		return;
	} 
	q->data[q->rear] = e;
	q->rear = (q->rear + 1) % MaxSize;//q->rear = q->rear + 1;普通顺序队列 
    
}

 出队: 

//出队
void deQueue(SqQueue* q )
{
	if (q->front == q->rear)
	{
		printf("队列为空,出不了!");
		return;
	}
	q->front = (q->front + 1)%MaxSize;//普通顺序队列:q->front = q->front + 1 ;
	 
}

遍历:遍历操作还有很多变形,比如说进行计算队列中含有多少元素。

void Print(SqQueue* q)
{
	if (q->front == q->rear)
	{		 
		return;
	}  
	for (int  i = q->front; i < q->rear; i++)
	{
		printf("%c", q->data[i]);
	}
}

 全部代码:

     (二)链队列

链队列就是将队列的元素用链表的形式来表示,设置头节点和尾结点来控制队列的尾入头出。

链队结点类型:

​
#define MaxSize 100
typedef char Data;
typedef struct DataNode
{
	Data data;
	struct DataNode *next;
} DataNode;//声明链队数据结点类型
typedef struct
{
	DataNode* front;
	DataNode* rear;
}LinkQueue;//声明链队类型

​

初始化链队:

LinkQueue*   InitQueue()
{
	LinkQueue*q = (LinkQueue*)malloc(sizeof(LinkQueue));
	assert(q);
	q->front = q->rear = NULL;
	return q;
} 

销毁队列:

​
void DestoryQueue(LinkQueue* q)
{
	DataNode* p = q->front, * r;
	if (p != NULL)
	{
		r = p->next;
		while (r != NULL)
		{
			free(p);
			p = r; r = p->next;
		}
	}
	free(p);
}

​

进队:

​
void enQueue(LinkQueue* q,Data e)
{
	DataNode* p = (DataNode*)malloc(sizeof(DataNode));
	assert(p);
	p->data = e;
	p->next = NULL;
	if (q->rear == NULL)
	{
		q->front = q->rear = p;//链队为空,新结点即是队首又队尾结点。
	}
	else
	{
		q->rear->next = p;//将p结点链到队尾,并将rear指向它
		q->rear = p;
	}
}

​

出队:

​
void deQueue(LinkQueue* q )
{
	DataNode* p;
	if (q->rear == NULL) return;
	p = q->front;//p指向队列第一个数据结点
	if (q->front == q->rear)
	{
		q->front = q->rear = NULL;
	}
	else
		q->front = q->front->next;
	free(p);
}

​

遍历:

void Print(LinkQueue*q)
{
	DataNode* p = q->front;
	if (p != NULL)
	{
		while (p->next != NULL)
		{
			printf("%c", p->data);
			p = p->next;
		}
	}
	assert(p);
	printf("%c", p->data);
 }

全部代码:

​
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#define MaxSize 100
typedef char Data;
typedef struct DataNode
{
	Data data;//数据域
	struct DataNode *next;//指针域
} DataNode;//声明链队数据结点类型
typedef struct
{
	DataNode* front;//队首指针
	DataNode* rear;//队尾指针
}LinkQueue;//声明链队类型
//初始化队列
LinkQueue*   InitQueue()
{
	LinkQueue*q = (LinkQueue*)malloc(sizeof(LinkQueue));
	assert(q);
	q->front = q->rear = NULL;
	return q;
}  
//销毁队列
void DestoryQueue(LinkQueue* q)
{
	DataNode* p = q->front, * r;
	if (p != NULL)
	{
		r = p->next;
		while (r != NULL)
		{
			free(p);
			p = r; r = p->next;
		}
	}
	free(p);
}
//判断队列是否为空
bool QueueEmpty(LinkQueue* q)
{	return q->rear == NULL;
}
//进队
void enQueue(LinkQueue* q,Data e)
{
	DataNode* news = (DataNode*)malloc(sizeof(DataNode));//创建新结点
	assert(news);
	news->data = e;
	news->next = NULL;
	if (q->rear == NULL)
	{
		q->front = q->rear = news;//链队为空,新结点即是队首又队尾结点。
	}
	else
	{
		q->rear->next =news;//将p结点链到队尾,并将rear指向它
		q->rear = news;
	}
}
//出队
void deQueue(LinkQueue* q )
{
	DataNode* p;
	if (q->rear == NULL) return;
	p = q->front;//p指向队列第一个数据结点
	if (q->front == q->rear)
	{
		q->front = q->rear = NULL;
	}
	else
		q->front = q->front->next;
	free(p);
}
void Print(LinkQueue*q)
{
	DataNode* p = q->front;
	if (p != NULL)
	{
		while (p->next != NULL)
		{
			printf("%c", p->data);
			p = p->next;
		}
	}
	assert(p);
	printf("%c", p->data);//补缺
 }
int main()
{
	Data e = ' ';
	LinkQueue* q = InitQueue();
	printf("依次进队列元素a,b,c,d\n");
	printf("链队为%s\n", QueueEmpty(q) ? "空" : "非空");
	enQueue(q, 'a');
	enQueue(q, 'b');
	enQueue(q, 'c');
	enQueue(q, 'd');
	Print(q);printf("链队为%s\n", QueueEmpty(q) ? "空" : "非空"); printf("\n依次删除队列元素:\n");
	deQueue(q);
	deQueue(q);
	Print(q); printf("\n");
	printf("链队为%s\n", QueueEmpty(q) ? "空" : "非空");
	enQueue(q,'d');
	Print(q);
	return 0;
}

​

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘 关

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值