4.线性表的循环链表、双向链表、以及应用

目录

思考

一.线性表的链式表示和实现内容?(What)

1.链式存储结构定义:

2.例子:线性表(赵、钱、孙、李)

3.例子:26个英文小写字母表的链式存储结构

4.链式存储术语

5.单链表、双链表、循环链表

6.头指针、头结点、首元结点

7.不带头结点、带头结点

讨论1:如何表示空表?

讨论2:在链表中设置头结点有什么好处?

讨论3:头结点的数据域内装的是什么?

8.链表特点

9.单链表的定义和表示

10.单链表操作

1.单链表的初始化

2.判断链表是否为空

3.单链表的销毁

4.清空链表

5.求单链表的表长

6.知识回顾

7.取值-取单链表中第i个元素

8.按值查找-根据指定数据获取该数据所在的位置(地址)

9.插入-在第i个节点前插入值为e的新节点

10.删除-删除第i个节点

11.单链表的查找、插入、删除算法时间效率分析

12.单链表:头插法

13.单链表:尾插法

二.为什么需要线性表的链式表示和实现?(Why)

1.顺序表的优缺点?

2.链表的优缺点?

3.链表分几类?

4.设置头结点有什么好处?

5.单链表的定义?

6.单链表操作(13种)

1.单链表的初始化

2.判断链表是否为空

3.单链表的销毁

4.清空单链表

5.求单链表的长度

6.取第i位置,返回该元素

9.插入-在第i个节点前插入值为e的新节点

10.删除-删除第i个节点

11.单链表:头插法

12.单链表:尾插法

三.如何学好线性表的链式表示和实现?(How)

1.多总结、多思考、多输出

2.用心


数据结构很重要!

数据结构很重要!!!

数据结构很重要!!!!

思考

1.线性表的链式表示和实现内容?(What)

2.为什么需要线性表的链式表示和实现?(Why)

3.如何学好线性表的链式表示和实现?(How)

注:特别感谢青岛大学王卓老师

第3章 栈和队列.pdf

一.线性表的链式表示和实现内容?(What)

总体内容概览:思维导图

1.链式存储结构定义:

结点存储位置是任意的,逻辑上位置跟物理上位置不同。

线性表的链式表示又称为非顺序映像链式映像

用一组任意的存储单元,来存放线性表的数据元素。

这组存储单元可以是连续的,也可以是不连续的,甚至是零散分布在内存中的任意位置上

2.例子:线性表(赵、钱、孙、李)

链表: 结点

存储地址 数据域 指针域

0112 李涵 0053

单链表:由头指针唯一确定,因此单链表可以用头指针的名字来命令。

3.例子:26个英文小写字母表的链式存储结构

逻辑结构:(a,b,c,d,....,z)

链式存储结构:head(头指针)->{数据域1,指针域1}->{数据域2,指针域2}->{..........}

数据域:存储元素数值数据

指针域:存储直接后继结点的存储位置

4.链式存储术语

结点:数据元素的存储映像

链表:n个结点由指针链接在一起组成一个链表。

5.单链表、双链表、循环链表

单链表:结点只有一个指针域的链表

双链表:结点有俩个指针域的链表。

循环链表:首尾相接的链表称为循环链表

6.头指针、头结点、首元结点

头指针:是指向链表中第一个结点的指针。

首元结点:链表中存储第一个数据元素a1的结点。

头结点:首元结点之前附设的一个结点。

7.不带头结点、带头结点

讨论1:如何表示空表?

无头结点:头指针为空时表述空表

有头结点:当头结点的指针域为空时表示空表

讨论2:在链表中设置头结点有什么好处?

有了头结点和后面首元结点处理是一样的。

讨论3:头结点的数据域内装的是什么?

头结点的数据域可以为空,也可以存放线性表长度。

头结点,不计入链表长度值。

8.链表特点

链表:顺序存储、逻辑位置和存储位置不一定相邻。

访问时只能通过头指针进入链表。然后通过每个结点的指针域依次向后顺序扫描其余结点。

顺序表:随机存取、逻辑位置和存储位置相邻。

9.单链表的定义和表示

单链表是:由表头唯一确定。

Lnode:结点。

Lnode a ; //定义一个节点a

a.data a.next

LinkList L; //L就是节点的一个指针

LNode *p 《==等价于==》LinkList L ;

10.单链表操作

1.单链表的初始化

  1. 分配内存空间
  2. L地址指向分配空间
  3. L->next = Null;

2.判断链表是否为空

空链表:链表中无元素

判断:头结点的指针域是否为空

int ListEmpty(LinkList L){

if(L->next) //非空

return 0;

else

return 1;

}

3.单链表的销毁

销毁:需要删除一个个节点(包括删除头结点、头指针)

  1. 头指针L指向头结点
  2. p指针 = L
  3. L=L->next;
  4. delete p (C++写法)

status DestroyList_L(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

}

4.清空链表

清空链表:头结点的指针域为空(头指针和头结点都在),清空其他元素。

status ClearList(LinkList &L){

Lnode *p,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next = Null;

return ok;

}

5.求单链表的表长

p=L->next

p=p->next

int ListLength(LinkList L){

LinkList p;

p=L->next;

int i=0;

while(p){

i++;

p=p->next;

}

return i;

}

6.知识回顾

1.单链表的销毁

statu Destory(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

return ok;

}

2.清空单链表

status ClearList(LinkList &L){

Lnode *p,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next=Null;

return ok;

}

3.求单链表的表长

int ListLength(LinkList L){

int i = 0 ;

Lnode *p;

p=L->next;

while(p){

i++;

p=p->next;

}

return i;

}

4.判断链表是否为空

status LinkListEmpty(LinkList L){

Lnode *p;

p=L->next;

if(p) return 1;

else return 0;

}

7.取值-取单链表中第i个元素

int GetElem(LinkList L,int i,ElemType &e){

Lnode *p;

p=L->next;

int j=1;

if(p&&j<i){

p=p->next;

j++;

}

if(!p||j>i) return error;

e=p->data;

return e;

}

8.按值查找-根据指定数据获取该数据所在的位置(地址)

int LocalElem(LinkList L, Elem e){

Lnode *p;

p=L->next;

int i =1;

if(p&&p->data!==e){

p=p->next;

i++;

}

if(!p) return 0;

return i;

}

9.插入-在第i个节点前插入值为e的新节点

Status ListInsert(LinkList &L,int i,ElemType e){

Lnode *p;

p=L; j=0;

while(p||j<i-1){

p=p->next;

++j;

}

if(!p||j>i-1) return error;

s=new Lnode ; s->data = e;

s->next=p->next;

p->next = s;

return ok;

}

10.删除-删除第i个节点

Status ListDelete_L(LinkList &L,int i,ElemType &e){

Lnode *p,*q;

p=L, j=0;

if(!p->next&&j<i-1){

p=p->next;

++j;

}

q=p->next;

p->next=q->next;

e=q->data;

delete q;

return ok;

}

11.单链表的查找、插入、删除算法时间效率分析

1.查找:O(n)

2.插入、删除:O(1)

12.单链表:头插法

void CreateList_H(LinkList &L,int n){

L=new LNode;

L->next=Null;

for(i=n;i>0;--i){

p=new LNode;

scanf(&p->data);

p->next=L->next;

L->next=p;

}

}

13.单链表:尾插法

void CreateList_R(LinkList &L,int n){

L=new LNode;

r=L;

for(i=0;i<n;++i){

p=new LNode;

scanf(p->data);

p->next=null;

r->next=p;

r=p;

}

}

二.为什么需要线性表的链式表示和实现?(Why)

1.顺序表的优缺点?

1.顺序表的优点:任意元素均可随机存取。

2.顺训表的缺点:进行插入和删除操作时,需要移动大量的元素,存储空间不灵活。

3.顺序表的特点:以物理位置相邻表示逻辑关系。

2.链表的优缺点?

1.链表优点插入、删除所耗费的时间复杂度为O(1),从头查找前驱结点消耗时间复杂度为O(n)。

2.链表缺点:只能顺序存取,查找时间为O(n)

3.链表的特点:逻辑上位置跟物理位置不一样,结点是任意存储的。

3.链表分几类?

  1. 单链表:结点只有一个指针域的链表
  2. 双链表:结点有俩个指针域的链表
  3. 循环链表:首尾相接的链表。

4.设置头结点有什么好处?

有了头结点,和后面处理首元结点是一样的。

5.单链表的定义?

单链表:由表头唯一确定。

存储结构:

typedef struct Lnode{

int data;

struct Lnode *next;

}Lnode,*LinkList

6.单链表操作(13种)

1.单链表的初始化

1.分配内存空间

2.L指向分配空间

3.L->next=Null

Status initList(LinkList L){

L=(LinkList)malloc(sizeof(Lnode));

L->next=Null;

}

2.判断链表是否为空

int emptyList(LinkList L){

if(L->next==null){

return 1; //为空

}else{

return 0;

}

}

3.单链表的销毁

销毁:需要删除一个个结点(包括头结点、头指针)

算法:从头指针开始,依次释放所有结点

status destoryList(LinkList &L){

Lnode *p;

while(L){

p=L;

L=L->next;

delete p;

}

}

4.清空单链表

头结点的指针域为空(头指针和头结点都在),删除其他元素

status CleanList(LinkList &L){

Lnode *p ,*q;

p=L->next;

while(p){

q=p->next;

delete p;

p=q;

}

L->next=Null;

return ok;

}

5.求单链表的长度

int LengthList(LinkList L){

Lnode *p;

int i = 0;

p=L->next;

while(p){

i++;

p=p->next;

}

return i;

}

6.取第i位置,返回该元素

int GetElem(LinkList L,int i,ElemType &e){

Lnode *p;

p=L->next;

int j=1;

if(p&&j<i){

p=p->next;

j++;

}

if(!p||j>i) return error;

e=p->data;

return e;

}

9.插入-在第i个节点前插入值为e的新节点

1.首先要找到a(i-1)的存储位置

2.生成一个数据域为e的新结点s

3.插入新结点:1.新结点的指针域指向ai

2.结点a(i-1)的指针域指向新结点

s->next=p->next

p->next=s

Status InsertList(LinkList &L,int i,ElemType e){

Lnode *p;

p=L,j=0;

while(p||j<i-1){

p=p->next;

++j;

}

if(!p||j>i-1) return error;

s=new Lnode;s->data=e;

s->next=p->next;

p->next=s;

return ok;

}

10.删除-删除第i个节点

Status deleteList(LinkList &L,int i){

Lnode *p;

p=L,j=0;

while(p||j<i-1){

p=p->next;

++j;

}

if(!p||j>i-1) return error;

q=p->next;

p->next=q>next;

delete q;

return ok;

}

11.单链表:头插法

1.从一个空表开始

2.生成新结点,将读入数据存放到新结点

3.新结点依次插入头部

void CreatList(LinkList &L,int n){

L=new Lnode;

L->next = null;

for(i=n;i>0;i--){

p=new Lnode;

scanf(&p->data);

p->next=L->next;

L->next=p;

}

}

12.单链表:尾插法

void CreatList(LinkList &L,int n){

L=new Lnode;

L->next = null;

int i;

for(i=0;i<n;++i){

p=new Lnode;

scanf(&p->data);

p->next=null;

r->next=p;

r=p;

}

}

三.如何学好线性表的链式表示和实现?(How)

1.多总结、多思考、多输出

多找案例,多练,多敲

2.用心

搞清楚,链表的定义,各种操作,扎实基础。

用心

用心、用心

用心、用心、用心

知其然、知其所以然!!!

多学习,多思考,多总结,多输出,多交流 (five kills)~~~

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

SuperBigData~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值