C语言 数据结构链队列的基本操作(附输入样例和讲解)

代码参照了严蔚敏、吴伟民编写的数据结构(C语言版)。
所有代码采用C语言编写。讲解请查看注释。

  • 注1:书中很多函数采用了引用传值,如InitQueue(LinkQueue &Q)。但C语言并不支持引用传值,因此统一改为地址传值,即InitQueue(LinkQueue *Q)。

头文件及宏定义

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define OK 1
#define False 0
#define True 1
#define Error 0

typedef定义数据类型和结构体

typedef int QElemType;
typedef int Status;

typedef struct QNode{
	QElemType data;
	struct QNode *next;
}QNode,* QueuePtr;

typedef struct{
	QueuePtr front;//队头指针 
	QueuePtr rear;//队尾指针 
}LinkQueue;

InitQueue(创建)

Status InitQueue(LinkQueue *Q){
	Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));//为头节点分配内存,剩下的节点创建时再进行分配。队头指针和队尾指针指向头节点 
	if(!Q->front)
	exit(OVERFLOW);
	Q->front->next=NULL;
	return OK;
}

DestroyQueue(销毁)

Status DestroyQueue(LinkQueue *Q){
	while(Q->front){//从头节点开始向后删除 
		Q->rear=Q->front->next;
		Q->front->data=0;
		free(Q->front);
		Q->front=Q->rear;
	}
	return OK;
}

ClearQueue(清空)

Status ClearQueue(LinkQueue *Q){
	QueuePtr temp=Q->front;//保存头节点 
	Q->front=Q->front->next;//获得第队头 
	while(Q->front){//从队头向后删除 
		Q->rear=Q->front->next;
		Q->front->data=0;
		free(Q->front);
		Q->front=Q->rear;
	}
	Q->front=temp;//使队头指针指向头节点 
	Q->rear=temp;//使队尾指针指向头节点
	return OK;
}

QueueEmpty(判断队列是否为空)

Status QueueEmpty(LinkQueue Q){
	if(Q.front==Q.rear)
	return True;
	else
	return False;
}

QueueLength(获得队列的长度)

int QueueLength(LinkQueue Q){
	int length=0;
	while(Q.front!=Q.rear){
		Q.front=Q.front->next;
		length++;
	}
	return length;
}

GetHead(获得队头元素)

Status GetHead(LinkQueue Q,QElemType *e){//若队列不空,用e返回队头元素 
	if(Q.front==Q.rear)
	return Error;
	*e=Q.front->next->data;
	return OK;
}

EnQueue( 队尾插入)

Status EnQueue(LinkQueue *Q,QElemType e){//插入元素e为新的队尾元素 
	QueuePtr p=(QueuePtr)malloc(sizeof(QNode));//为插入的新节点申请内存,使p指向新节点 
	if(!p)
	exit(OVERFLOW);//内存分配失败 
	p->data=*e;
	p->next=NULL;//将插入到队尾 
	Q->rear->next=p;//插入 
	Q->rear=p;//更改队尾指针,使其指向这个元素 
	return OK;
}

DeQueue(队头删除)

Status DeQueue(LinkQueue *Q,QElemType *e){//从队头删除一个元素,用e返回 
	if(Q->front==Q->rear)//空队的话无法删除 
	return Error; 
	QueuePtr p;
	p=Q->front->next;//p指向队头元素 
	*e=p->data;
	p->data=0;
	Q->front->next=Q->front->next->next;//p指向的队头元素将被删除,所以原队头指针指向下一个元素 
	if(Q->front->next==Q->rear)//如果只有一个队内元素的话(除去头节点),删除后为空队 
	Q->rear=Q->front;
	free(p);
	return OK;
}

QueueTraverse(遍历)

首先需要实现Visit()

Status visit(LinkQueue Q){
	while(Q.front!=Q.rear){
		printf("%d\n",Q.front->next->data);
		Q.front=Q.front->next;
	}
	return OK;
}
Status QueueTraverse(LinkQueue Q,Status visit()){
	visit(Q);
	return OK;
} 

输入样例

很多函数被我注释掉了,需要使用的话自行取消注释。

int main(void){
	LinkQueue Q;
	InitQueue(&Q);
	int elem1=1,elem2=2,elem3=3;
	EnQueue(&Q,elem1);
	EnQueue(&Q,elem2);
	EnQueue(&Q,elem3);//向队列中插入三个数值 
	//ClearQueue(&Q);
	//QueueEmpty(Q);
	//int elem4=0,elem5=0;
	//DeQueue(&Q,&elem4);//删除了队头元素1并存储在elem4中
	//GetHead(Q,&elem5);//获取新的队头元素2并存储在elem5中
	//QueueLength(Q);
    QueueTraverse(Q,visit);
	DestroyQueue(&Q);

}

输出结果

输出结果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值