链式队列的基本操作(c语言实现)

队列类型定义:
队列的操作与栈的操作类似,不同的是,删除是在队头进行。
队列分类
** 顺序队列**:与栈相似(数组),无非就是多了一个指针。
简单的讲讲顺序队列,元素入队,队尾指针往后加一,元素出队,队头指针往后加一。
现在我们设想一下,前面有一个数组,我们先存放了一些数据入队,后面进行出队操作,之后再入队,那么此时,假设,一个数组a的大小为10,经过这些操作之后,队头元素在a[99],此时如果我们还要进行操作时,发现队列的长度不够了,但是实际上,a[99]前面仍然有一大片空间没有被利用,这种现象我们称之为"假溢出"。为了避免"假溢出"现象,此时我们使用循环队列。循环队列将在下一章详细介绍。
** 链式队列**:链式队列是指采用链表存储结构实现的队列。根据队列的性质,链表需要两个指针,队头,队尾各一个指针,队头进行出队操作,队尾进行入队操作。
链式队示意图:
在这里插入图片描述
要注意的是有一个头结点不存放数据,这一点和链表相似。
基本操作:

  1. 初始化队列
  2. 判断队列是否为空
  3. 元素入队
  4. 遍历队列
  5. 取首元素
  6. 元素出队且撤销申请空间

代码:
下面是分块代码,后面有完整代码。
初始化队列

#pragma once
# include <stdio.h>
# include <stdlib.h>
typedef int ElemType;
typedef struct QNODE
{
 int data;    //存放数据
 struct QNODE *next;  //指针域
}QNODE,*PQNODE;
typedef struct
{
 PQNODE front;   
 PQNODE rear;   
}QUEUE;
**void InitQueue(QUEUE *L)
{
 L->front = L->rear = (PQNODE)malloc(sizeof(QNODE));
 L->front->next =L->rear->next= NULL;    
}

判断队列是否为空

int EmptyQueue(QUEUE *L)
{
 if (L->front->next == NULL)  
 {
  printf("队列已空!\n");
  return 1;
 }
 else
  return 0;
}

元素入队

void PushQueue(QUEUE *L, ElemType e)
{
 PQNODE s = (PQNODE)malloc(sizeof(QNODE));
 s->next = NULL;
 s->data = e;
 L->rear->next = s;
 L->rear = s;
} 

遍历队列

void TraverseQueue(QUEUE *L)
{
 PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 t = L->front;
 t = t->next;
 while (t != NULL)
 {
  printf("%3d->", t->data);
  t = t->next;
 }
}

取首元素

void GetQueueFirstItem(QUEUE *L, ElemType *e)
{
 PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 t = L->front;
 t = t->next;    //指向有效节点
 *e = t->data;
}

元素出队且撤销申请空间****

void OutQueue(QUEUE *L)
{
 PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 t = L->front;
 while (L->front->next != NULL)
 {
  L->front = L->front->next;
  printf("%5d->", t->next->data);
  free(t);
  t = L->front;
 }
}

头文件代码:

#pragma once
# include <stdio.h>
# include <stdlib.h>
typedef int ElemType;
typedef struct QNODE
{
 	int data;    //存放数据
 	struct QNODE *next;  //指针域
}QNODE,*PQNODE;
typedef struct
{
 	PQNODE front;   //队头(指针)进行删除
 	PQNODE rear;   //队尾(指针)压入数据
}QUEUE;
//队列初始化
void InitQueue(QUEUE *L)
{
 	L->front = L->rear = (PQNODE)malloc(sizeof(QNODE));
 	L->front->next =L->rear->next= NULL;    //是使队头,队尾的指针域指向空,而不是让队头队尾为空
}
int EmptyQueue(QUEUE *L)
{
 	if (L->front->next == NULL)  //队头的指针域为空,即后面即没有元素连接
 	{
  		printf("队列已空!\n");
  		return 1;
 	}
 	else
  	return 0;
}
//压入元素
void PushQueue(QUEUE *L, ElemType e)
{
 	PQNODE s = (PQNODE)malloc(sizeof(QNODE));
 	s->next = NULL;
 	s->data = e;
 	//尾插法
 	L->rear->next = s;
 	L->rear = s;
} 
void DeleteQueue(QUEUE *L, ElemType*e)
{
 	if (EmptyQueue(L))
 	{
  		printf("队列已空,无法出队!\n");
  		return;
 	}
 	else
 	{
  	//队列有一个头结点,所以需要指针往后移一个单元,指向有效数据
  		PQNODE m = (PQNODE)malloc(sizeof(QNODE));
  		m = L->front;
  		m = m->next;     //指向有效数据
  		*e = m->data;
  		PQNODE t = (PQNODE)malloc(sizeof(QNODE));
  		t = L->front;
  		L->front = L->front->next;  //头结点往后移
  		free(t);  //释放头结点
 	}
}
//取队头元素
void GetQueueFirstItem(QUEUE *L, ElemType *e)
{
 //用一个临时结点来指向队头,因为队列的操作一般不会直接用头结点进行操作,否则很容易使后面的操作混乱
 	PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 	t = L->front;
 	t = t->next;    //指向有效节点
 	*e = t->data;
}
void TraverseQueue(QUEUE *L)
{
 	PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 	t = L->front;
 	t = t->next;
 	while (t != NULL)
 	{
 	 	printf("%3d->", t->data);
  		t = t->next;
 	}
}
//元素全部出队,并撤销空间
void OutQueue(QUEUE *L)
{
 //这时可以直接对队头进行操作
 	PQNODE t = (PQNODE)malloc(sizeof(QNODE));
 	t = L->front;
 	while (L->front->next != NULL)
 	{
  		L->front = L->front->next;
  		printf("%5d->", t->next->data);
  		free(t);
  		t = L->front;
 	}
}

源文件代码:

# include <stdio.h>
# include <stdlib.h>
# include "Queue.h"
int main()
{
	QUEUE L;
	InitQueue(&L);
	int a[10];
 	printf("请输入数据!\n");
 	for (int i = 0; i < 10; i++)
 	{
  		scanf("%d", &a[i]);
  		PushQueue(&L, a[i]);
 	}
 	printf("抛出队头元素!\n");
 	int e;
 	GetQueueFirstItem(&L, &e);
 	printf("队头元素为:%d", e);
 	printf("\n");
 	printf("遍历队列!\n");
 	TraverseQueue(&L);
 	printf("删除元素(队头)!\n");
 	DeleteQueue(&L, &e);
 	printf("删除的元素为:%d\n",e);
 	printf("删除所有元素,并且撤销所有空间!\n");
 	OutQueue(&L);
 	system("pause");
 	return 0;
}

代码运行截图:
在这里插入图片描述

  • 11
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值