【数据结构】关于链表中间插入的引用

稍微记录一下接下来复习的一些想法。

这两天开始复习王道的数据结构,又看到了关于链表的中间插入的代码。

书籍中在插入的函数传递参数时,使用的C++的引用类型,具体可以参照《C++ Primer Plus》中的解释。

王道书籍中描写中间插入时是这样的:

当时就衍生出一个疑问,L是指针类型,存放的是地址,对于普通的函数形参传递,即值传递,将会在函数内开辟内存空间以创建并初始化形参变量,这就意味着函数内部的形参将不再与外界传递的实参内存地址等同。而对于指针而言,就是内部和外部的指针的地址不一致,但是实际上对于指针内存放的值也就是节点的地址是无影响的,这也就是意味着在中间插入时无论我是否指定引用,都会完成节点的中间插入而更新原实参L链表。

更形象的来说,相当于外界有一个原链表指针L指向节点A,而进入函数之后,发生局部变量创建复制,无非是多了另外一个不同指针本身地址的链表指针L1指向节点A,即L和L1两个链表指针所存储的值是相同的。从最后的插入结果来看,所以无论是否使用引用都是可以完成的。

整体代码如下(比较懒,就使用了数据结构之单链表(c语言附完整代码)_数据结构_hello_world&&-GitCode 开源社区代码做一下测试):

#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode  
{
	ElemType data;
	struct LNode *next;		//指向后继结点
} LinkNode;					//声明单链表结点类型

void CreateListR(LinkNode *&L,ElemType a[],int n)
//尾插法建立单链表
{
	LinkNode *s,*r;
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
	r=L;					//r始终指向终端结点,开始时指向头结点
	for (int i=0;i<n;i++)
	{	
		s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
		s->data=a[i];
		r->next=s;			//将结点s插入结点r之后
		r=s;
	}
	r->next=NULL;			//终端结点next域置为NULL
}
void InitList(LinkNode *&L)
{
	L=(LinkNode *)malloc(sizeof(LinkNode));  	//创建头结点
	L->next=NULL;
}

bool ListEmpty(LinkNode *L)
{
	return(L->next==NULL);
}
int ListLength(LinkNode *L)
{
	LinkNode *p=L;int i=0;
	while (p->next!=NULL)
	{	i++;
		p=p->next;
	}
	return(i);
}
void DispList(LinkNode *L)
{
	LinkNode *p=L->next;
	while (p!=NULL)
	{	printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
}


bool ListInsert(LinkNode *L,int i,ElemType e)
{
	printf("插入中链表地址:%d\n",&L);
	printf("插入中链表的头节点地址:%d\n",L->next);
	int j=0;
	LinkNode *p=L,*s;
	if (i<=0) 
	   return false;			//i错误返回假
	while (j<i-1 && p!=NULL)		//查找第i-1个结点p
	{	j++;
		p=p->next;
	}
	if (p==NULL)					//未找到位序为i-1的结点
		return false;
	else							//找到位序为i-1的结点*p
	{	s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点*s
		s->data=e;
		s->next=p->next;			//将s结点插入到结点p之后
		p->next=s;
		return true;
	}
}

int main()
{
	LinkNode *L;
	ElemType e;
	ElemType a[]={1,2,3,4};

	CreateListR(L,a,4);        //尾插法建立链表
	printf("头插法所得顺序为:");
	DispList(L);
	printf("链表的长度为:%d\n",ListLength(L));
	printf("插入前链表的头节点地址:%d\n",L->next);
	printf("插入前链表地址:%d\n",&L);
	ListInsert(L,4,5);          //在链表第四个元素前插入5 
	printf("插入一个元素后链表的元素为:");
	DispList(L);
	printf("插入后链表的头节点地址:%d\n",L->next);
	printf("插入后链表地址:%d\n",&L);

}

使用引用时测试结果如下:

不使用引用时,测试结果如下:

可以看到在两次测试中链表都完成了中间插入的功能,只是在无引用时插入中的链表地址发送了改变。

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值