引:
本文用来记录c语言数据结构队列的实现,先了解指针与结构体的作用,完成了队列初始化,入队,出队功能(我用的是vsstdio2022);其他功能以后继续更新
指针与结构体的简单认识:
结构体:
1.存储多种类型变量的一种变量
2.一般用typedef关键字将结构体类型名转为变量定义,方便后面编程
如:
typedef unsigned char snack_type; //节点存储数据的类型
typedef struct LinkNode
{
snack_type data; //结点的内容
struct LinkNode* next; //连接下一个结点的指针
}LinkNode; //结构体类型名称——非实际结构体变量
3.结构体名并不是地址
4.结构体可以用结构体变量名.结构体成员名或者(*指向结构体指针变量名.)结构体成员名【(指向结构体指针变量名->结构体成员名)也可以】,来对结构体成员赋值,
指针
1.用来间接引用变量,主要是可以在自设的函数中去改变实际的变量
2.队列头尾指针结构体变量有结构体变量与结构体指针变量,结构体变量用来存储数据,结构体指针变量用来调用结构体变量
疑问:(可以不看,对接下来实现队列联系不大)
1.在上例的结构体LinkNode中其实际占了16个字节?
——占的是9个字节,因为内存并不是连续给结构体分配9个字节,不同类型的变量并没有连续存储,但是我理解应该是9个字节(因为我使用的VSstdio用的64位,指针占8位字节;结构体的指针成员与其他成员相隔了四个字节
关于这个问题,我对结构体新创建了2个int变量
typedef struct LinkNode {
snack_type data; //结点的内容
/*short a;*/
int a, b;
struct LinkNode* next; //连接下一个结点的指针
}LinkNode; //结构体类型名称——非实际结构体变量
这是结构体的内存
而再增加一个unsigned char与short类型后
typedef struct LinkNode {
snack_type data; //结点的内容
snack_type da;
short s;
int a, b;
struct LinkNode* next; //连接下一个结点的指针
}LinkNode; //结构体类型名称——非实际结构体变量
新结构体内存
2.指针在函数运行中的思考:
首先在函数给一个局部指针变量p用malloc创造空间,现在创建了一个可使用内存(假设为s),地址在局部指针变量中,但是将这个值赋值给传递进来的指针变量是没用的(为什么),但是如果作为返回值赋值给指针变量即可以,
现在知道s与addrs(s的地址)是真实的,p,addrp都是暂时的
队列的实现
1.首先创建队列的节点结构体类型——包含存储内容以及指向下一个节点的指针,如上例的结构体LinkNode
2.然后创建队列头尾指针结构体类型,用于找到队列,与队列的增减
例如
typedef struct LinkQueue_point //队列头尾指针结构体
{
LinkNode* front; //头指针
LinkNode* rear; //尾指针
}LinkQueue_point;
3.建立队列头尾指针结构体变量,存储头尾指针,建立队列头尾指针结构体指针变量,用来调用头尾指针——(这样在函数中也能改变头尾指针)
LinkQueue_point save_point_Queue = {NULL,NULL}; //队列头尾指针结构体变量
LinkQueue_point* point_Queue = &save_point_Queue; //队列头尾指针结构体指针变量
4.队列初始化函数:
将头尾指针指向创建的头结点结构体变量
//brief功能:建立队列的结构体指针变量以及头结点,并将头尾指针指向头结点
//param参数:无
//retva返回值:队列头尾指针结构体指针变量
LinkQueue_point* LinkheadNode_init()
{
LinkQueue_point* pq = &save_point_Queue;
LinkNode* head = (LinkNode*)malloc(sizeof(LinkNode)); //队列头结点,是指针
if (head != NULL) //头结点创建内存成功
{
head->next = NULL; //可以代替下面注释的两句
pq->front = head;
pq->rear = head;
//pq->front->next = NULL;
//pq->rear->next = NULL;
}
return pq;
}
用图表示:
5.入队函数:增加节点,并把数值加入
代码如下:
//brief功能:队列结点增加
//param参数:队列头尾指针结构体指针变量,要存储的变量
//retval返回值:无
void LinkQueue_add(LinkQueue_point* point, snack_type num)
{
LinkNode* node = (LinkNode*)malloc(sizeof(LinkNode)); //新建立一个结点结构体内存,将地址给node指针变量
if (node != NULL) //结点创建内存成功
{
//给新建结点赋值
node->data = num;
node->next = NULL;
point->rear->next = node; //先将队列与新建结点建立联系
point->rear = node;
}
}
用图表示
5.出队函数:从头指针处删去一个节点并取出数值
代码如下:需要定义变量
//变量定义
snack_type testnum = 1; //存储删去节点的数据的变量
snack_type* p_save = &testnum; //指向存储变量的指针,可以在函数中将数值存入存储变量
//brief功能:队列结点减少,并将队列结点数值给接收的指针变量
//param参数:队列头尾指针结构体指针变量,队列结点数值
//retval返回值:0:队列为空,1:成功
int LinkQueue_reduce(LinkQueue_point* point, snack_type* p_save)
{
if (point->front->next == NULL) //队列为空
{
return 0;
}
LinkNode* temporary_variable = point->front->next; //将临时变量指向要删除的结点
//p_save = &(temporary_variable->data); //保存数值,这行不行,同疑问的第二点
*p_save = temporary_variable->data;
point->front->next = temporary_variable->next; //将队列头结点连接下一个结点
if (temporary_variable == point->rear) //只有一个数据结点
point->rear = point->front;
/*free(point->front->next);*/
free(temporary_variable); //释放结点,同上一句
return 1;
}
错误:
1.LNK1168
无法打开VS编程\24年上学期\point_testV0\x64\Debug\point_testV0.exe 进行写入 point_testV0 C:\Users\31441\Documents\VS编程\24年上学期\point_testV0\point_testV0\LINK 1
现象:编译无法成功
原因:使用malloc函数后,在检验时出现的问题;应该是指针错误使用
解决:删除vs保存的文件中这个位置
删除这个,会提示你无法删除,我用火绒的强制删除删除了,然后重新编译就可以了。