C语言之链式队列

在写程序之前先说明一下链式队列的一些特点。

1.首先链式队列和数组队列一样遵循FIFO即先进的先出。

2.链式队列和数组队列不同之处在于数组队列在内存中是连续存储的,而链式队列是由指针的指向将相邻两个元素进行连接的,因此在内存中链式队列并不是连续存储的。具体情况如下:

那么开始构建链式队列了!

       首先我们定义队列中每个节点的数据类型,因为链式队列节点之间需要指针建立关系,因此每个节点包含数据域和指针域,节点定义如下

struct Node
{
    int data; //为了方便这里设置为整型数据,可以是任意类型的数据,包括结构体类型也是可以的
    struct Node* next;   //指针域,用于指向下一个节点的地址
}

       构建好每个节点的结构体后,还要构建队列的结构体,因为队列里面有两个非常重要的成员:头指针和尾指针。

struct Queue
{
    struct Node* front;   //头指针
    struct Node* tail;   //尾指针
    int sz;    //记录队列中节点个数
}

       这里我们用到了一个sz,这个数据主要是用来记录队列中节点个数的,定义sz可以简化我们的代码。   

       头指针指向队列的第一个元素,也就是相对于其他节点来说第一个进入队列的元素,尾指针指向队列的最后一个元素,也就是相对于其他节点来说最后一个进入队列的元素。这里说相对是因为队列有入队和出队的操作,进行一次入队和出队后,就会有一些变化啦,这个后面再说。

       将节点和队列的结构体构建好后,就可以开始写构建队列和构建节点的函数了

//构建队列,函数返回指向新建的队列的指针
struct Queue* creatQueue()
{
    //在堆区申请一块内存由于保存队列的头尾指针
	struct Queue* myqueue = (struct Queue*)malloc(sizeof(struct Queue));
    //初始化阶段将头尾指针置为空
	myqueue->front = myqueue->tail = NULL;   
    //节点数为0
	myqueue->sz = 0;
	return myqueue;
}
//构建节点,函数返回指针新建的节点的指针
struct Node* creatNode(int data)
{
	struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
	newnode->data = data;
	newnode->next = NULL;
	return newnode;
}

运行前面的构建队列的函数之后,我们就得到了一个空的队列了。有了队列之后,就可以进行入队和出队操作了。

因为队列遵循先进先出原则,因此每次入队都是进入队尾,而每次出队都是队头元素弹出。

//入队
void push(struct Queue* myqueue, int data)
{
	struct Node* newnode = creatNode(data);    //创建要入队的节点
	if (myqueue->sz == 0)   
	{//如果队列为空,则队头指针和队尾指针都指向这个新节点
		myqueue->front = myqueue->tail = newnode;
	}
	else
	{//否则队尾指针一开始指向的节点的指针域指向新的节点,然后再让队尾指针指向这个新的节点
     //因为我们的队尾指针要遵循指向队列的最后一个节点 这个原则
		myqueue->tail->next = newnode;   
		myqueue->tail = newnode;
	}
	myqueue->sz++;   //别忘了入队操作后,节点数加1,所以sz要加1
}
//出队
void pop(struct Queue* myqueue)
{
	if (myqueue->sz == 0)
	{//如果队列为空则无法出队,直接结束函数
		printf("队列为空,无法出队\n");
		return;
	}
	else
	{//队列不为空的情况下,我们定义一个指针指向第二个元素,因为出队后第二个元素就会变成队头了
		struct Node* cur = myqueue->front->next;
		free(myqueue->front);   //free掉队头元素
		myqueue->front = cur;  //让队头指针指向第二个元素,此时第二个元素相对来说就是第一个元素了
		myqueue->sz--;       //别忘了出队后,节点数减1,sz也要减1了
	}
}

现在最主要的两个函数入队和出队已经写好了,还需要写一些辅助函数来让我们的队列用起来更方便,比如获取队头元素,打印队头元素,判断队列是否为空

//获取队头元素
int getFront(struct Queue* myqueue)
{
	return myqueue->front->data;   //直接返回队头节点的数据域
}
//打印队头元素
void print(struct Queue* myqueue)
{
	printf("%d ", myqueue->front->data);
}
//判断队列是否为空
int empty(struct Queue* myqueue)
{
	if (myqueue->sz == 0)
		return 1;         // 如果为空则返回1
	else
		return 0;         //不为空则返回0
}

关于我们需要的一些辅助函数已经写好了,那么现在试一下我们写的队列吧!

主函数

int main()
{
	struct Queue* myqueue = creatQueue();    //创建队列
    //入队
	push(myqueue, 1);    
	push(myqueue, 2);
	push(myqueue, 3);
	push(myqueue, 4);
	push(myqueue, 5);
	push(myqueue, 6);

	while (!empty(myqueue))   //当队列不为空
	{
		print(myqueue);    //打印队头元素
		pop(myqueue);      //出队
	}
	return 0;
}

完整代码

#include<stdio.h>
struct Node
{
	int data;
	struct Node* next;
};

struct Queue
{
	struct Node* front;
	struct Node* tail;
	int sz;
};

struct Node* creatNode(int data)
{
	struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
	newnode->data = data;
	newnode->next = NULL;
	return newnode;
}

struct Queue* creatQueue()
{
	struct Queue* myqueue = (struct Queue*)malloc(sizeof(struct Queue));
	myqueue->front = myqueue->tail = NULL;
	myqueue->sz = 0;
	return myqueue;
}

//入队
void push(struct Queue* myqueue, int data)
{
	struct Node* newnode = creatNode(data);
	if (myqueue->sz == 0)
	{
		myqueue->front = myqueue->tail = newnode;
	}
	else
	{
		myqueue->tail->next = newnode;
		myqueue->tail = newnode;
	}
	myqueue->sz++;
}

//出队
void pop(struct Queue* myqueue)
{
	if (myqueue->sz == 0)
	{
		printf("队列为空,无法出队\n");
		return;
	}
	else
	{
		struct Node* cur = myqueue->front->next;
		free(myqueue->front);
		myqueue->front = cur;
		myqueue->sz--;
	}
}

//获取队头元素
int getFront(struct Queue* myqueue)
{
	return myqueue->front->data;
}

//判断队列是否为空
int empty(struct Queue* myqueue)
{
	if (myqueue->sz == 0)
		return 1;
	else
		return 0;
}

//打印队头元素
void print(struct Queue* myqueue)
{
	printf("%d ", myqueue->front->data);
}

int main()
{
	struct Queue* myqueue = creatQueue();
	push(myqueue, 1);
	push(myqueue, 2);
	push(myqueue, 3);
	push(myqueue, 4);
	push(myqueue, 5);
	push(myqueue, 6);

	while (!empty(myqueue))
	{
		print(myqueue);
		pop(myqueue);
	}
	return 0;
}

输出结果为

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值