当前位置:   article > 正文

嘉明的数据结构学习Day3——单链表的头插法和尾插法_为什么列表的头插法和尾插法是要有引用的

为什么列表的头插法和尾插法是要有引用的

链表

链表的定义

在这里插入图片描述
其中链表的定义有带头结点和不带头结点,带头的结点操作起来更方便容易
头指针的优点
在这里插入图片描述

单链表结点的定义

在这里插入图片描述

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

typedef int ElemType;
//定义链表的结点
typedef struct LNode {
	ElemType data;//数据域
	struct LNode* next;//指针域
}LNode, * LinkList;//别名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

其中插入操作中有头插法和尾插法,下面我们一一介绍

头插法

头插法顾名思义就是插在头结点的后面
代码如下:

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

typedef int ElemType;
//定义链表的结点
typedef struct LNode {
	ElemType data;//数据域
	struct LNode* next;//指针域
}LNode, * LinkList;//别名

//头插法,即从头结点后面插入。比如输入的是12345,插入之后可能顺序就是54321
LinkList creatList1(LinkList& L) {
	LNode* s;//定义要插入的指针
	int x;//定义需要插入的数据域
	L = (LinkList)malloc(sizeof(LNode));//头结点,没有数据域(默认值)。用于表明这是指针
	L->next = NULL;//因为头结点的指向下一个结点,但是还没定义所以是NULL
	scanf("%d", &x);
	//使用9999作为中止循环的结束符
	while (x != 9999) {
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;//把数据赋值给插入结点的数据域
		s->next = L->next;//把指针指向的下一个结点赋给插入的结点的指针(头插法)
		L->next = s;//然后再把指针指向的结点指向插入的结点
		scanf("%d", &x);//再次读取数据知道x等于9999为止
	}
	return L;
}

int main() {
	LinkList L;
	creatList1(L);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这里插入图片描述
可以看到我们输入的顺序是3 4 5 6但是得到的结果确实 6 5 4 3。这就是头插法。
在这里插入图片描述

尾插法

思路添加一个尾结点,这样头结点就可以指向下一个元素之后保持不变了,只需要尾结点移动即可。

//尾插法,即从头结点后面插入。比如输入的是12345,插入之后可能顺序就是12345
LinkList creatList_Tail(LinkList& H) {
	LNode *s,*r;//定义要插入的结点和表尾结点
	int x;//定义需要插入的数据域
	H = (LinkList)malloc(sizeof(LNode));//头结点,没有数据域(默认值)。用于表明这是指针
	r = H;//链表为空尾指针指向头结点
	scanf("%d", &x);
	//使用9999作为中止循环的结束符
	while (x != 9999) {
		s = (LinkList)malloc(sizeof(LNode)); //申请空间创建新的结点
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return H;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
在这里插入图片描述

脑短路以及解决

问题

一开始做头插法的时候,看到了下面这个函数,想到了引用

LinkList creatList1(LinkList& L)
  • 1

我就在想,既然LinkList本来就是一个指针

LinkList L
  • 1

L本来就是一个指针变量存的是地址,引用是实际上是别名(但是理解的太肤浅了),那为什么我不直接这样定义

LinkList creatList1(LinkList L)
  • 1

把&删掉呢?反正L传的都是地址。我们直接传过去对地址进行操作不是一样吗?
就像这样

LinkList creatList1(LinkList L)//错误的

int main() {
	LinkList L;
	creatList_Head(L);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

我以为拿到了指针L把地址传过去,形参里的L是在操作主函数的L了。。。。

解决方法以及总结

然后我就去搜索,直到看到了这篇文章我恍然大悟。
https://blog.csdn.net/HurryRabbit/article/details/105524133
它说道:
地址也只是一个"无符号的整型"数据,其本身也跟普通变量一样是值的传递, 区别在于,我们可以通过这个值来去物理内存中找到的具体地址空间, 然后对这个地址空间进行访问。

形参只得到了传过去的地址。不意为着你就再操作这个形参的指针变量就是操作实参!!!!!
但是你可以通过✳+形参的指针变量来改变实参指针变量所指向的值。

但我们需要的使用p=malloc来申请空间。所以如果这样下去也只是形参得到申请空间,但是使局部变量,函数运行完毕就被系统销毁,所以实参只做了传递地址而没有申请到空间。
其实只是把地址传过去,形参又是系统在栈开辟的一个新的指针变量,你只是把地址传过去而已,没有进行任何操作使主函数的L改变

其实引用不是单纯的起别名,实质原理就是二级指针不过简化了而已。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/444151
推荐阅读
相关标签
  

闽ICP备14008679号