数据结构(使用C语言)队列

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构(使用C语言)队列相关的知识,希望对你有一定的参考价值。

对顺序循环队列,常规的设计方法是使用队尾指针和队头指针,队尾指针用于指出当前胡队尾位置下标,队头指针用于指示当前队头位置下标。现要求:
(1)设计一个使用队头指针和计数器胡顺序循环循环队列抽象数据类型,其中包括:初始化,入队列,出队列,取队头元素肯判断队列是否非空;
(2)编写一个主函数进行测试

对顺序循环队列,常规的设计方法是使用队尾指针和队头指针,队尾指针用于指出当前胡队尾位置下标,队头指针用于指示当前队头位置下标。现要求:
(1)设计一个使用队头指针和计数器胡顺序循环循环队列抽象数据类型,其中包括:初始化,入队列,出队列,取队头元素肯判断队列是否非空;
#include "stdio.h"
#include "malloc.h"
#include "stdlib.h"
#include "conio.h"
#define MAX 80
typedef struct


int data[MAX];

int front,rear;

int num;
SeQue;
SeQue *Init_SeQue()


SeQue *s;

s=new SeQue;

s->front=s->rear=MAX-1;

s->num=0;

return s;

int Empty_SeQue(SeQue *s)


if(s->num==0)

return 1;

else

return 0;

int In_SeQue(SeQue *s,int x)


if(s->num==MAX)

return 0;

else

 

s->rear=(s->rear+1)%MAX;

s->data[s->rear]=x;

s->num++;

return 1;

 
 
int Out_SeQue(SeQue *s,int *x)

if(Empty_SeQue(s))

return 0;
else


s->front=(s->front+1)%MAX;

*x=s->data[s->front];

s->num--;

return 1;


void Print_SeQue(SeQue *s)


int i,n;
i=(s->front+1)%MAX;
n=s->num;
while(n>0)
 printf("%d ",s->data[i]);

i=(i+1)%MAX;

n--;


void main()


SeQue *s;

int k,flag,x;

s=Init_SeQue();

do

printf("\\\\\\");

printf("\\\\t\\\\t\\\\t循环顺序队列\\");

printf("\\\\t\\\\t\\\\t***********************\\");

printf("\\\\t\\\\t\\\\t**1-入队**\\");

printf("\\\\t\\\\t\\\\t**2-出队**\\");

printf("\\\\t\\\\t\\\\t**3-判 队 空**\\");

printf("\\\\t\\\\t\\\\t**4-队列显示**\\");

printf("\\\\t\\\\t\\\\t**0-返回**\\");

printf("\\\\t\\\\t\\\\t***********************\\");

printf("\\\\t\\\\t\\\\t 请输入菜单项(0-4):");

scanf("%d",&k);

switch(k)



case 1:


printf("\\请输入入队元素:");


scanf("%d",&x);


flag=In_SeQue(s,x);


if(flag==0)


printf("\\队满不能入队!按任意键返回..");


else


printf("\\元素已入队!按任意键返回..");


getch();


system("cls");


break;

case 2:


flag=Out_SeQue(s,&x);


if(flag==0)


printf("\\队列空出队失败!按任意键返回..");


else


printf("\\队列头元素已出队~!按任意键返回..");


getch();


system("cls");


break;

case 3:


flag=Empty_SeQue(s);


if(flag==1)


printf("\\该队列为空!按任意键返回..");


else


printf("\\该队列不为空!按任意键返回..");


getch();


system("cls");


break;

case 4:


printf("\\该队列元素为:");


Print_SeQue(s);


printf("\\按任意键返回..");


getch();


system("cls");


break;



while(k!=0);
参考技术A #include "stdio.h"
#include "malloc.h"
#include "stdlib.h"
#include "conio.h"
#define MAX 80
typedef struct

int data[MAX];
int front,rear;
int num;
SeQue;
SeQue *Init_SeQue()

SeQue *s;
s=new SeQue;
s->front=s->rear=MAX-1;
s->num=0;
return s;

int Empty_SeQue(SeQue *s)

if(s->num==0)
return 1;
else
return 0;

int In_SeQue(SeQue *s,int x)

if(s->num==MAX)
return 0;
else

s->rear=(s->rear+1)%MAX;
s->data[s->rear]=x;
s->num++;
return 1;


int Out_SeQue(SeQue *s,int *x)

if(Empty_SeQue(s))
return 0;
else

s->front=(s->front+1)%MAX;
*x=s->data[s->front];
s->num--;
return 1;


void Print_SeQue(SeQue *s)

int i,n;
i=(s->front+1)%MAX;
n=s->num;
while(n>0)
printf("%d ",s->data[i]);
i=(i+1)%MAX;
n--;


void main()

SeQue *s;
int k,flag,x;
s=Init_SeQue();
do
printf("\n\n\n");
printf("\t\t\t 循环顺序队列\n");
printf("\t\t\t***********************\n");
printf("\t\t\t** 1-入 队 **\n");
printf("\t\t\t** 2-出 队 **\n");
printf("\t\t\t** 3-判 队 空 **\n");
printf("\t\t\t** 4-队列显示 **\n");
printf("\t\t\t** 0-返 回 **\n");
printf("\t\t\t***********************\n");
printf("\t\t\t 请输入菜单项(0-4):");
scanf("%d",&k);
switch(k)

case 1:
printf("\n请输入入队元素:");
scanf("%d",&x);
flag=In_SeQue(s,x);
if(flag==0)
printf("\n队满不能入队!按任意键返回..");
else
printf("\n元素已入队!按任意键返回..");
getch();
system("cls");
break;
case 2:
flag=Out_SeQue(s,&x);
if(flag==0)
printf("\n队列空出队失败!按任意键返回..");
else
printf("\n队列头元素已出队~!按任意键返回..");
getch();
system("cls");
break;
case 3:
flag=Empty_SeQue(s);
if(flag==1)
printf("\n该队列为空!按任意键返回..");
else
printf("\n该队列不为空!按任意键返回..");
getch();
system("cls");
break;
case 4:
printf("\n该队列元素为:");
Print_SeQue(s);
printf("\n按任意键返回..");
getch();
system("cls");
break;

while(k!=0);
本回答被提问者采纳

(C语言)手撕数据结构之——队列

目录

队列的概念及结构

队列的实现方式

数组队列

链式队列

链式队列的实现

初始化队列

入队列

出队列

获取队列头部元素

获取队列尾部元素

获取队列中有效元素个数

检测队列是否为空

销毁队列

实现队列的全部代码

测试用例


队列的概念及结构

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出 FIFO(First In First Out)。

入队列:进行插入操作的一端称为队尾。

出队列:进行删除操作的一端称为队头。

队列的实现方式

实现队列有两种方式:1.用数组实现,2.用链表实现。

数组队列

缺点:元素出队列时需要将后面的数据向前面挪,效率比较低。

链式队列

在队列中保存指向队头队尾的两个指针,出队时只需将指向队头的指针指向原队头的下一个,入队时直接在队尾的后面入即可

故使用链表的结构实现会更优一点。

链式队列的实现

首先创建该队列中单个元素的结构体,然后创建一个队列结构体,包含指向头、尾两个指针。

typedef int QDataType;

typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

下面给出需要实现的接口:

//初始化队列
void QueueInit(Queue* pq);

//入队列
void QueuePush(Queue* pq, QDataType x);
//出队列
void QueuePop(Queue* pq);

//获取队列头部元素
QDataType QueueFront(Queue* pq);
//获取队列队尾元素
QDataType QueueBack(Queue* pq);

//获取队列中有效元素个数
int QueueSize(Queue* pq);

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);

//销毁队列
void QueueDestroy(Queue* pq);

初始化队列

队列初始化只需将指向头、尾的两个指针指向空即可。

void QueueInit(Queue* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
}

入队列

首先申请空间创建该元素,如果队列中无元素,则将该元素作为队列的头和尾;如果队列中有元素,则直接将该元素连接到队列的尾处,并将队列的尾指针指向该元素。

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QNode* newNode = (QNode*)malloc(sizeof(QNode));
	if (newNode == NULL)
	{
		printf("malloc fail\\n");
		exit(-1);
	}

	newNode->data = x;
	newNode->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}

出队列

出队列时先检测队列中是否有元素,若队列中无元素,则应让程序直接报错。

有元素时分为一个或多个元素:

一个元素:直接释放该节点,并将原队列中的头、尾指针指向空。

多个元素:先保存头指针指向节点的下一个节点,然后释放头节点,并将头指针指向原保存值。

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);//若队列为空,无元素可出队列,直接报错

	//1.一个元素
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
    //2.多个元素
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

获取队列头部元素

获取元素时先检测队列是否有元素,若无元素则直接报错,有元素则返回头指针指向节点的数据。

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

获取队列尾部元素

与获取队头元素相类似。

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);

	return pq->tail->data;
}

获取队列中有效元素个数

从队头开始遍历整个队列并计数即可,遍历时应创建一个新的变量进行遍历,保证不改变头指针。

int QueueSize(Queue* pq)
{
	assert(pq);

	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

检测队列是否为空

如果为空返回非零结果,如果非空返回0

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

销毁队列

队列中每个元素都为新开辟的节点,故需要逐个销毁。将所有节点销毁完后将头、尾指针指向空。

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}

实现队列的全部代码

#include <stdio.h>
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>

typedef int QDataType;

typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;

typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;

//初始化队列
void QueueInit(Queue* pq);

//队尾入
void QueuePush(Queue* pq, QDataType x);
//队头出
void QueuePop(Queue* pq);

//获取队列头部元素
QDataType QueueFront(Queue* pq);
//获取队列队尾元素
QDataType QueueBack(Queue* pq);

//获取队列中有效元素个数
int QueueSize(Queue* pq);

//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);

//销毁队列
void QueueDestroy(Queue* pq);

void QueueInit(Queue* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
}

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);

	QNode* newNode = (QNode*)malloc(sizeof(QNode));
	if (newNode == NULL)
	{
		printf("malloc fail\\n");
		exit(-1);
	}

	newNode->data = x;
	newNode->next = NULL;

	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newNode;
	}
	else
	{
		pq->tail->next = newNode;
		pq->tail = newNode;
	}
}

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	//1.一个
	//2.多个
	if (pq->head->next == NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);

	return pq->head->data;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);

	return pq->tail->data;
}

int QueueSize(Queue* pq)
{
	assert(pq);

	int size = 0;
	QNode* cur = pq->head;
	while (cur)
	{
		size++;
		cur = cur->next;
	}
	return size;
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->head == NULL;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
}

测试用例

void TestQueue()
{
	Queue q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
    printf("%d ", QueueBack(&q));

	QueuePop(&q);
	printf("%d ", QueueFront(&q));
	QueuePop(&q);
	printf("%d ", QueueFront(&q));

	QueuePush(&q, 3);
	QueuePush(&q, 4);
	QueuePush(&q, 5);

    printf("QueueSize:%d\\n", QueueSize(&q));

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\\n");

	QueueDestroy(&q);
}

int main()
{
    TestQueue();
    return 0;
}

以上是关于数据结构(使用C语言)队列的主要内容,如果未能解决你的问题,请参考以下文章

数据结构c语言如何实现循环队列

(C语言)手撕数据结构之——队列

数据结构复习笔记——队列(c语言)

C语言队列

C语言实现一个优先队列

[数据结构] 队列 (C语言)