数据结构与算法——单链表的整表操作

 

目录

前言

一、单链表的整表创建

二、单链表的整表删除


前言

回顾一下,顺序储存结构的创建,其实就是数组的初始化,即声明一个类型和大小的数组并赋值的过程。而单链表和顺序储存结构就不一样,它不像顺序储存结构一样那么集中,它可以很散,类似于一种动态结构。对于每个链表来说,它所占用的空间的大小和位置是不需要预先分配划定的,可以根据系统的情况和实际的需求即时生成。

所以,创建单链表的过程就是一个动态生成链表的过程。


一、单链表的整表创建

算法思路如下:

  1. 声明一指针p和计数器变量i;
  2. 初始化一个空链表a;
  3. 让a的头结点的指针指向NULL,即建立一个带头结点的单链表。
  4. 循环:
  • 生成一新结点赋值给p;
  • 随机生成一数字赋值给p的数据域p.data;
  • 将p插入到头结点与前一新结点之间。

实现代码如下:

void createlist(linklist *a,int n)
{
	linklist p;
	int i;
	srand(time(0));         //初始化随机数种子 
	*a=(linklist)malloc(sizeof(node));
	(*a).next=NULL;         //先建立一个带头结点的单链表 
	for(i=0,i<n,i++)
	{
		p=(linklist)malloc(sizeof(node));    //生成新结点 
		p.data=rand()%100+1;                 //随机生成100以内的数字 
		p.next=(*a).next;
		(*a).next=p;                         //插入到表头 
	}
}

在这段代码里,我们用的是插队的办法,就是始终让新结点在第一的位置。称之为头插法

可事实上,这不符合我们的正常思维。正所谓先来后到,我们可以把新结点都插在终端结点的后面,这种算法称之为尾插法。

实现代码算法如下:

 

void createlisttail(linklist *a,int n)
{
	linklist p,r;
	int i;
	srand(time(0));           //初始化随机种子 
	*a=(linklist)malloc(sizeof(node));     //a为整个线性表 
	r=*a;                 //r为指向尾部的结点 
	for(i=0;i<n;i++)
	{
		p=(node*)malloc(sizeof(node));     //生成新结点 
		p.data=rand()%100+1;               //随机生成100以内的数字 
		r.next=p;                          //表尾终端结点指向新指针 
		r=p;                               //将当前定义的新结点定义为表尾的终端结点 
	}
	r.next=NULL;                    //表示当前链表结束 
	
}

这里需要我们注意a与r的关系,a是指整个单链表,而r是指向尾指针的变量,r会随着循环不断的变化结点,而a则是随着循环增长为一个多节点的链表。

可能会有很多同学不理解r=p的含义,这里其实就是一个新结点被创造出来了,原来的r结点就不是尾结点了,尾结点其实是新创造出来的p。所以将p赋值给r,则r又是最终的尾结点了。

循环结束后,那么应该让这个结点的指针域置空,因此有了“r.next=NULL”,以便于以后遍历时可以确认其是尾部。

二、单链表的整表删除

当我们不打算使用这个单链表时,我们需要把它销毁,其实也就是在内存中将它放掉,以便于留出空间给其他程序或软件使用。

算法思路如下:

  1. 声明两指针p和q;
  2. 将第一个结点赋值给p;
  3. 循环
  • 将下一结点赋值给q;
  • 释放p;
  • 将q赋值给p;

实现代码如下:

status clearlist(linklist *a)
{
	linklist p,q;
	p=(*a).next;          //p指向第一个指针 
 	while(p)              //没到表尾 
	{
		q=p.next;
		free(p);
		p=q;
		
	}
	(*a).next=NULL;       //头结点指针域为空 
	
	return ok;
}

这里有一个很多同学都容易犯的错误,就是觉得q变量没有存在的必要。直接写free(p);p=p.next即可。但是,变量q的最大作用就在于它使得下一个结点是谁得到了记录,以便于当前结点释放后,把下一结点拿回来补充。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值