数据结构 前 链表

回来了,今天心情好再更新一个。

链表分为单链表,双链表,循环链表。

前文我们说到,线性表他是一个连续的空间,但是 我们如果 a1 然后后面都没有 一直到a2000 那中间的话你如果用线性表的话是不是会造成资源空间浪费?所以说。这时候采取线性表是不好的。那我们该怎么办?这里就引入了单链表。

链表是一种物理存储单元上非连续、非顺序的数据结构

那我们怎么想呢?链表他是不是一个线?是不是每个元素之间都有关系?哦,当然是,那我们怎么表示?他是不是要具备元素信息和元素序号。信息是不是data 序号是不是指针?

那链表我们就可以用指针+data来构造 这就是我们一开始所想的。

链表由一系列结点(链表中每一个元素称为结点)组成,每一次为一个结构体 动态分配的内存空间,可称之为一个结点,每个结点之间可以是不连续的,但结点内是连续的。结点个数是不受限定的,可以随时删改,这是与数组相比的优点。

结点由指针域和数据域构成。结点之间的联系可以用指针实现,即在结点结构体中定义一个成员项来存放下一结点的首地址,该成员被称为指针域。第n个结点的指针域内存入第n+1个结点的首地址,如此串联下去直到最后一个结点(尾结点),其指针域为NULL,被称为空指针,表示该链表结束。(这是官方定义的)

单链表分为带头单链表和不带头单链表

在这里插入图片描述

 使用不使用头这个null的 他的关键是看你的操作会不会操作到a1 个人观点,尽可能情况下都使用带头结点,代码方便,可操行强!

这里介绍两个函数 malloc 和free 函数

malloc函数:malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存,且分配的大小就是程序要求的大小。

这个和c++中的new有着异曲同工之妙 大家可以看看c++中的new

free() 就是释放内存。

这里我们都需要用到

首先 我们要建立单链表;

需要什么? 一个工作指针 一个头结点 

int CreateListTail(Linklist &L,int n){
    LNode *s,*p;
    L=(Linklist *)malloc(sizeof(LNode));//创建头结点
    L->next = NULL; //将头结点next域置空
    s=L;//s,l同时指向头结点,开始时头结点和尾结点是同一个

    for(int i=0;i<n;i++){
      p=(LNode *)malloc(sizeof(LNode));//创建数据结点,函数malloc分配了一个LNode类型的结点空间,并将其首地址存入指针变量p中
	  scanf("%d",&p->data);
      s->next=p;//新结点插入到当前链表的表尾
      s=p;//使s指向尾结点
    }

}

这些创建的代码的名字,虽然理论上你咋定义都可以。但是你要为监考老师,为工作,更是为了以后提桶跑路后你的代码接手的新人。还是这种官方统一的比较合适。

s是尾指针 p是工作指针;L(linklistl)是头指针。那个Lnode还需要自己再定义 就是之前我们说的那个数据域和指针域。c的话需要typedef struct 记住了 不是c++直接struct

这样就可以创建好一个单链表了。

那创建好了我们就要增删查了

那就先查找吧 查找的话不需要对链表进行改变 不需要用*;

这个就像key-value一样 我们现在要查东西,肯定不给你指针,因为给了就给出了他的位置

所以她肯定是让你用value(值)来查找到

int getelem2(Linklist L, ElemType e)
{
	int i=0;
	Lnode *p = L->next;
	while (p!=NULL&&p->data!=e)当p指向的不是空值域然后p这个数据指向的结果不是e的时候
	{
		p = p->next;
		i++;
	}
	if(p!=NULL)return(i);
	else return p,i;
}

那接下来就是插入的操作了

怎么插入呢?是不是先建立一个这个,上图

在这里插入图片描述

 咱们先创建一个和ai那个一样的 让他也指向ai+1;然后可以改变了让ai那个指针指向e,改变一下意思就是3这条路被1和2给段了 

int ListInsert(LinkList &L,int i ,ElemType e)
{
LNode *p,*s; 
p = L;
int j = 0;
while (p && j<i-1) /*寻找第i-1个结点*/
    {
    p = p->next;
    ++j;
    }
if (!p || j >i)
    return ERROR;  /*第i个元素不存在*/

s = (LNode)malloc(sizeof(Node)); /*生成新的结点*/
s->data = e;
s->next = p->next;  /*将p的后继结点赋值给s的后继*/
p->next = s;  /*将s赋值给p的后继*/
return OK;
}

那么删除是不是也是同一个道理?只要我们把旁边的两个指针给相连 不和中间的ai连,是不是就把ai给他断了,就可以删除了,当然,记得free()一下,清理内存

int ListInsert(LinkList &L,int i ,ElemType e)
{
LNode *p,*s; 
p = L;
int j = 0;
while (p && j<i-1) /*寻找第i-1个结点*/
    {
    p = p->next;
    ++j;
    }
if (!p || j >i)
    return ERROR;  /*第i个元素不存在*/

s = (LNode)malloc(sizeof(Node)); /*生成新的结点*/
s->data = e;
s->next = p->next;  /*将p的后继结点赋值给s的后继*/
p->next = s;  /*将s赋值给p的后继*/
return OK;
}

好了,我要去打cf了

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子买5斤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值