单链表学习过程

链表的特点:用一组任意的储存单元储存线性表的数据元素。

结点(存储印象):1.储存本身的信息~~数据域

                                 2.储存直接后继元素的储存位置(一个指示其后继元素的信息)~~指针域

补充:1.链\指针:指针域中存储的信息

           2. 链表:由n个结点链结成

头指针:链表中第一个结点的存储位置

头结点:1.有时我们会在第一个结点之前附设一个结点

               2. 其数据域一般不放数据,但也可存储如线性表的长度等的附加信息           

               3.其指针域存储指向第一个结点的指针

首元结点:链表中第一个元素所在的结点,头结点后边的第一个结点

线性表的单链表储存结构:

typedef struct LNode{ //结点的类型定义(结构体类型)
	Elentype data; //结点的数据域
	struct LNode *next; //结点的指针域:一个指针,变量名叫next,类型是struct Lnode
}LNode,*Linklist;

解释:

1.elen:是单词element的缩写,意为在程序定义中代表某一不确定的类型,也就是抽象的数据类型。为了使程序可读性强,并且便于修改,让elem代表多种的数据类型,也就是为int、char等等的数据类型,起了一个别名。

2.ElemType是数据结构的书上为了说明问题而用的一个词。它是element type(“元素的类型”)的简化体因为数据结构是讨论抽象的数据结构和算法的,一种结构中元素的类型不一定是整型、字符型、浮点型或者用户自定义类型,为了不重复说明,使用过程中用“elemtype”代表所有可能的数据类型,简单明了的概括了整体。在算法中,除特别说明外,规定ElemType的默认是int型。在头文件中定义:
typedef char elem;
抽象元素类型为char类型,这样定义之后,下面的程序中elem所定义的元素就是char类型的了 
又例如,使用:typedef int ElemType; 定义ElemType为int类型

3.括号外的*Linklist是当前这个值的地址,只是这个值里有数据data,和下一个值的地址(指向这一结构体的一个指针)

4.括号里的是一个指针,变量名叫next,类型是struct Lnode*

5.括号外LNode是对struct LNode结构体的重命名

存储顺序:

若p指向的是第i个数据元素的指针,则p->next是指向第i+1个数据元素的指针。

即:若p->data=ai,则p->next->data=ai+1

补充:单链表中要取得第i个元素就必须从头指针出发寻找,因为,单链表是非随机存储的。

来看例题吧π-π

eg1:一个书上的例子~函数GetElem在单链表中的表现

	Status GetElem_L(LinList L,int i,ElemType &e)//定义一个名叫GetElem_L的单链表
    {                                            //L为带头结点的单链表的头指针
	p=L->next;
    j=1;        //p指向的是首元结点,j为计数器
	while(p&&j<i)//按顺序查找,直到p指向第i个指针或者p为空
	{
		p=p->next;
        ++j;
	} 
	if(!p||j>i)//第i个元素不存在
	return ERROR;
	e=p->data;//第i个元素存在且取到了
	return OK;
	} 

解释:

1.数据结构中status 的意思

算法开头status 是一种数据类型的别名,这单词是状态的意思,如返回 的是状态信息,就用status 声明函数返回类型。而通常用以下的语句说明status:如typedef int status ;这说明其实status和int 型是相同的,它大致上是用来返回本函数是否执行成功,它的几个取值OK,ERROR,OVERFLOW也在同时定义使用的时候把这些东西定义成一个头文件,使用Stauts的文件,包含这个头文件即可

2.线性表表函数GetElem(L,i,&e)是用e返回L中第i个元素的值.

3.if(!p||j>i)return ERROR;

这句我不晓得是啥意思,好难啊我不想学了气死了我哭了

单链表中我们怎样才能实现插入呢?

1.已知:要在a结点和b结点之间插入一个结点x,p为单链表存储结构中指向结点a的指针

2.思路:为在a结点和b结点插入数据x,首先要生成一个数据域为x的结点,然后插入单链表中;

           然后修改结点a中的指针域,使其指向结点x;

            结点x中的指针域应指向结点b。

3.假设:s为指向结点x的指针

4.实现语句为:

	s->next=p->next;    //结点x的指针域s指向下一个结点b的指针域,而b的指针域用一开始没有插入之前的的表示方式,即a结点的指针域p指向的下一个指针域
	p->next=s;    //p是结点a的指针域,指向下一个结点x的指针域s

单链表中我们怎样才能实现删除呢?

1.思路:仅需要修改结点a中的指针域

2.实现语句:

p->next=p->next->next;

总结:在单链表中插入或删除一个结点时,仅需修改指针而不需要修改移动元素。

例1:插入结点

	Status ListInsert_L(LinkList &L,int i,Elemtype e)
    {         //在L中的第i个位置之前插入元素e
		p=L;
		j=0;
		while(p&&j<i-1)//寻找第i-1个结点
		{
			p=p->next;
			++j;
		}
	if(!p||j>i-1)//第i个元素不存在
	return ERROR;
	s=(LinkList)malloc(sizeof(LNode));//开辟一个内存空间,存的是指针变量s
	s->data=e;    结点s中的元素是e
	s->next=p->next;    //插入的结点s的下一个结点是原来没有插入时的下一个结点
	p->next=s;        //第一个结点p后面的结点不是next而是现在插入的结点s
	return OK;
	} 

解释:

1.ListInsert(LinkList &L,int i,Elemtype e)链表函数:是用来在单链表L的第i个位置之前插入元素e,几个取值OK,ERROR,OVERFLOW。

2.malloc函数

int *p;

p = (int *)malloc( sizeof(int) );//malloc向系统申请一个sizeof(int)大小的内存空间

由系统生成一个LNode型的结点,同时将该结点的起始位置赋给指针变量p

例2:删除结点

Status ListDelete_L(LinkList &L,int i,Elemtype &e)
    {        
		p=L;
		j=0;
		while(p->next&&j<i-1)
		{
			p=p->next;
			++j;
		}
	if(!(p->next)||j>i-1)
	return ERROR;    //删除地方不合理时返回ERROR
	q=p->next;
    p->next=q->next;
    e=q->data;
    free(q);   //删除并释放结点   
	return OK;
	} 

解释:

1.free(e):由系统回收一个结点,回收后的空间可以备作再次生成结点时用。

结论:单链表的存储空间可以为多个链表共同享有,按系统需求使用生成,因此,建立线性表的链式储存结构的过程就是一个动态生成链表的过程。即从空表建起,依次建立各个元素结点,并逐个插入链表。

我这个先学到这了,然后等下一篇哇,我学不懂了,下一篇估摸着是头插法和尾插法吧。我学不会了完了完蛋了。

  • 9
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值