数据结构C语言版:链队的建立和初始化,入队,出队,判断是否为空,取队头元素
前言
注意:数据结构学习一定需要结合图形来理解,尤其是先理解图的做法,然后在编写代码,思考了之后在动手,这样效率会更好。不要急于动手,冷静下来思考, 想这一步我该如何用我学习的知识解决。
提示:以下是本篇文章正文内容,下面案例可供参考
一、基本思路
链队的基本思路:第一步,链~~想到结点, 结点是不是需要指针和数据域。 第二步,队头,队尾指针该如何设置。 第三步:入队,出队和循环队列有什么区别(注意:队的操作规则:先进先出(尾插法))。按照上面思考,解决了基本就能写出这个链队。二、实现过程
1.结点生成
代码如下(示例):
第一步:生成一个结点数据类型, 然后生成一个具体的结点
typedef struct QNode
{
struct QNode *next; //指针域
char data; //数据
}QNode;
//生成结点
QNode *init_node()
{
QNode *q;
q = (struct QNode*)malloc(sizeof(struct QNode)); //申请内存空间
q->next = NULL;
return q;
}
2.队头队尾指针设置
代码如下(示例):
//创建两个队头,尾指针指向队列(类型为QNode)
typedef struct
{
QNode *rear; //尾指针
QNode *front; //头指针
//两个种类必须相同才能指向类型为QNode的结点
}Link_Queue;
//生成一个只含头结点的链表(尾插法)
void create_link_Queue(Link_Queue *Q)
{
QNode *head = init_node();
Q->rear = head;
Q->front = head;
} //初始化链队, 相同于循环队列的Q->next = Q->front = 0, 只不过现在指向结点的地址
3.入队和出队
代码如下(示例):
//入队(不需要判断队满的情况, 在内存允许的情况下, 是可以无限的,哈哈哈)
void enter(Link_Queue *Q, char x)
{
QNode *p = init_node(); //每次入队都生成一个结点
p->data = x;
Q->rear->next = p;
Q->rear = p;
}
//出队(队头出)
char pop(Link_Queue *Q)
{
if(isEmpty(*Q))
{
printf("队空");
exit(0); //退出程序
}
QNode *p = init_node();
char e;
p = Q->front->next;
e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
{
Q->front = Q->rear; //如何删除的是队尾最后一个元素的结点,则表示出队以后为空
}
delete p;
return e;
}
三、代码实现
代码如下(示例):
//
// Created by xoo on 2021/6/30.
//
//链队的建立以及基本操作(初始化, 入队, 出队, 取队头元素)
#include<stdio.h>
#include<stdlib.h>
#include<string>
//生成结点
typedef struct QNode
{
struct QNode *next; //指针域
char data; //数据
}QNode;
//创建两个队头,尾指针指向队列(类型为QNode)
typedef struct
{
QNode *rear; //尾指针
QNode *front; //头指针
//两个种类必须相同才能指向类型为QNode的结点
}Link_Queue;
//生成一个结点
QNode *init_node()
{
QNode *Q;
Q = (struct QNode*) malloc(sizeof (struct QNode));
Q->next = NULL;
return Q;
}
//生成一个只含头结点的链表(尾插法)
void create_link_Queue(Link_Queue *Q)
{
QNode *head = init_node();
Q->rear = head;
Q->front = head;
} //初始化链队, 相同于循环队列的Q->next = Q->front = 0, 只不过现在指向结点的地址
//入队(不需要判断队满的情况, 在内存允许的情况下, 是可以无限的,哈哈哈)
void enter(Link_Queue *Q, char x)
{
QNode *p = init_node(); //每次入队都生成一个结点
p->data = x;
Q->rear->next = p;
Q->rear = p;
}
//判断是否为空
bool isEmpty(Link_Queue Q)
{
if(Q.rear == Q.front)
{
return true; //判断是否为空的条件
}
return false;
}
//出队(对头出)
char pop(Link_Queue *Q)
{
if(isEmpty(*Q))
{
printf("队空");
exit(0); //退出程序
}
QNode *p = init_node();
char e;
p = Q->front->next;
e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
{
Q->front = Q->rear; //如何删除的是队尾最后一个元素的结点,则表示出队以后为空
}
delete p;
return e;
}
//取对头元素
char get_head_elem(Link_Queue *Q)
{
if(isEmpty(*Q))
{
printf("队空");
exit(0);
}
return Q->front->next->data;
}
//打印函数
void display(Link_Queue *Q)
{
while(!isEmpty(*Q))
{
printf("%c->", pop(Q));
}
printf("NULL");
}
int main()
{
Link_Queue *queue;
create_link_Queue(queue); //生成一个链表
for (char i = 'A'; i < 'F'; i++)
{
enter(queue, i); //进队
}
printf("取对头元素:");
printf("%c", get_head_elem(queue));
printf("\n出队:\n");
display(queue);
printf("\n");
system("pause");
return 0;
}
结果:
取对头元素:A
出队:
A->B->C->D->E->NULL
总结
链栈的基本操作和其他链表的方式基本一致,只不过出队的时候,先进来的先出去,而不像链栈一样是逆置。打好基础是继续学习坚固堡垒。
这是小编所用的软件,喜欢这种可以下载,过程有点麻烦,但是非常好用,背景可以自己设置。