数据结构第3章链表.docx

上传人:b****1 文档编号:2299791 上传时间:2022-10-28 格式:DOCX 页数:36 大小:80.86KB
下载 相关 举报
数据结构第3章链表.docx_第1页
第1页 / 共36页
数据结构第3章链表.docx_第2页
第2页 / 共36页
数据结构第3章链表.docx_第3页
第3页 / 共36页
数据结构第3章链表.docx_第4页
第4页 / 共36页
数据结构第3章链表.docx_第5页
第5页 / 共36页
点击查看更多>>
下载资源
资源描述

数据结构第3章链表.docx

《数据结构第3章链表.docx》由会员分享,可在线阅读,更多相关《数据结构第3章链表.docx(36页珍藏版)》请在冰豆网上搜索。

数据结构第3章链表.docx

数据结构第3章链表

第3章链表

一、复习要点

本章重点讨论最简单的链表结构——单链表。

详细地介绍了单链表的抽象数据类型,单链表的类定义,相应操作的实现,引入了带表头结点的单链表结构。

进一步定义了用模板描述的单链表类。

作为一种应用,讨论了一元多项式的类定义及其加法操作的实现。

此外,讨论了循环链表和双向链表。

在复习这一章时需要对C++语言中的指针和引用类型的使用有清楚的理解。

对带表头结点的链表和不带表头结点的链表在插入、删除、搜索时的差别有清楚的认识。

而且需要明确:

链表是一种实现级的结构。

本章复习的要点:

1、基本知识点

单链表是一种线性结构,链表各结点的物理存储可以是不连续的,因此各结点的逻辑次序与物理存放次序可以不一致。

必须理解单链表的定义和特点,单链表的抽象数据类型和类定义,单链表成员函数,如构造函数、搜索、插入、删除等操作的实现,对比带表头结点单链表的搜索、插入、删除操作,比较其优缺点。

其次是循环链表的定义和特点,它与单链表的差别,它的搜索、插入、删除操作的实现。

最后是双向链表的定义,它的插入与删除操作的实现。

2、算法设计

单链表的迭代求解算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,单链表各结点顺序逆转算法,在单链表中按从左到右和从右到左的顺序遍历的逆转链算法。

带表头结点的单链表的迭代算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,连续删除链表中含有value值的结点,两个有序链表的合并。

单链表的递归算法,包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,求链表各结点值的和,求链表各结点的值的平均值。

循环链表的迭代算法:

包括统计链表结点个数,在链表中寻找与给定值value匹配的结点,在链表中寻找第i个结点,在链表中第i个位置插入新结点,删去第i个结点,将循环链表链入单链表的表头。

多项式的建立,两个多项式的相加,两个多项式的相减。

用单链表实现字符串操作,每个结点仅存一个字符。

二、难点和重点

1、单链表:

单链表定义、相应操作的实现。

单链表的两种定义方式(复合方式与嵌套方式)

单链表的搜索算法与插入、删除算法

单链表的递归与迭代算法

2、循环链表:

单链表与循环链表的异同

3、双向链表:

带表头结点的双向循环链表

双向循环链表的定义,带表头结点的优点

双向链表的搜索、插入与删除算法

4、多项式:

多项式的定义、多项式的表示及加法

多项式.的三种表示

多项式链接表示的优点

多项式加法的实现(有序链表的合并算法)

三、教材中习题的解析

3-1线性表可用顺序表或链表存储。

试问:

(1)两种存储表示各有哪些主要优缺点?

(2)如果有n个表同时并存,并且在处理过程中各表的长度会动态发生变化,表的总数也可能自动改变、在此情况下,应选用哪种存储表示?

为什么?

(3)若表的总数基本稳定,且很少进行插入和删除,但要求以最快的速度存取表中的元素,这时,应采用哪种存储表示?

为什么?

【解答】

(1)顺序存储表示是将数据元素存放于一个连续的存储空间中,实现顺序存取或(按下标)直接存取。

它的存储效率高,存取速度快。

但它的空间大小一经定义,在程序整个运行期间不会发生改变,因此,不易扩充。

同时,由于在插入或删除时,为保持原有次序,平均需要移动一半(或近一半)元素,修改效率不高。

链接存储表示的存储空间一般在程序的运行过程中动态分配和释放,且只要存储器中还有空间,就不会产生存储溢出的问题。

同时在插入和删除时不需要保持数据元素原来的物理顺序,只需要保持原来的逻辑顺序,因此不必移动数据,只需修改它们的链接指针,修改效率较高。

但存取表中的数据元素时,只能循链顺序访问,因此存取效率不高。

(2)如果有n个表同时并存,并且在处理过程中各表的长度会动态发生变化,表的总数也可能自动改变、在此情况下,应选用链接存储表示。

如果采用顺序存储表示,必须在一个连续的可用空间中为这n个表分配空间。

初始时因不知道哪个表增长得快,必须平均分配空间。

在程序运行过程中,有的表占用的空间增长得快,有的表占用的空间增长得慢;有的表很快就用完了分配给它的空间,有的表才用了少量的空间,在进行元素的插入时就必须成片地移动其他的表的空间,以空出位置进行插入;在元素删除时,为填补空白,也可能移动许多元素。

这个处理过程极其繁琐和低效。

如果采用链接存储表示,一个表的存储空间可以连续,可以不连续。

表的增长通过动态存储分配解决,只要存储器未满,就不会有表溢出的问题;表的收缩可以通过动态存储释放实现,释放的空间还可以在以后动态分配给其他的存储申请要求,非常灵活方便。

对于n个表(包括表的总数可能变化)共存的情形,处理十分简便和快捷。

所以选用链接存储表示较好。

(3)应采用顺序存储表示。

因为顺序存储表示的存取速度快,但修改效率低。

若表的总数基本稳定,且很少进行插入和删除,但要求以最快的速度存取表中的元素,这时采用顺序存储表示较好。

3-2针对带表头结点的单链表,试编写下列函数。

(1)定位函数Locate:

在单链表中寻找第i个结点。

若找到,则函数返回第i个结点的地址;若找不到,则函数返回NULL。

(2)求最大值函数max:

通过一趟遍历在单链表中确定值最大的结点。

(3)统计函数number:

统计单链表中具有给定值x的所有元素。

(4)建立函数create:

根据一维数组a[n]建立一个单链表,使单链表中各元素的次序与a[n]中各元素的次序相同,要求该程序的时间复杂性为O(n)。

(5)整理函数tidyup:

在非递减有序的单链表中删除值相同的多余结点。

【解答】

单链表的结点类(ListNodeclass)和链表类(Listclass)的类定义。

#ifndefLIST_H//将单链表定义在List.h

#defineLIST_H

templateclassList;//前视的类定义

templateclassListNode{//链表结点类的定义

friendclassList;//List类作为友元类定义

private:

Typedata;//数据域

ListNode*link;//链指针域

public:

ListNode():

link(NULL){}//仅初始化指针成员的构造函数

ListNode(Typeitem,ListNode*next=NULL):

data(item),link(next){}

//初始化数据与指针成员的构造函数

ListNode*getLink(){returnlink;}//取得结点的下一结点地址

TypegetData(){returndata;}//取得结点中的数据

voidsetLink(ListNode*next){link=next;}//修改结点的link指针

voidsetData(Typevalue){data=value;}//修改结点的data值

};

templateclassList{//单链表类定义

private:

ListNode*first,*current;//链表的表头指针和当前元素指针

public:

List(Typevalue){first=current=newListNode(value);}//构造函数

~List(){MakeEmpty();deletefirst;}//析构函数

voidMakeEmpty();//将链表置为空表

intLength()const;//计算链表的长度

ListNode*Find(Typevalue);//搜索含value的元素并成为当前元素

ListNode*Locate(inti);//搜索第i个元素并置为当前元素

TypeGetData(){returncurrent->data;}//取出表中当前元素的值

intInsert(Typevalue);//将value插在当前位置后并成为当前元素

Type*Remove();//将表中当前元素删去,填补者为当前元素

ListNode*Firster(){current=first;returnfirst;}//当前指针定位于表头

TypeFirst(){;//当前指针定位于表第一个元素并返回值

Type*Next();//将当前指针进到表中下一个元素并返回值

intNotNull(){returncurrent!

=NULL;}//表中当前元素空否?

空返回1,不空返回0

intNextNotNull(){returncurrent!

=NULL&¤t->link!

=NULL;}

};//当前元素的下一元素空否?

空返回1,不空返回0

(1)实现定位函数的算法如下:

templateListNode*List:

:

Locate(inti){

//取得单链表中第i个结点地址,i从1开始计数,i<=0时返回指针NULL

if(i<=0)returnNULL;//位置i在表中不存在

ListNode*p=first;intk=0;//从表头结点开始检测

while(p!

=NULL&&klink;k++;}//循环,p==NULL表示链短,无第i个结点

returnp;//否则k==i,返回第i个结点地址

}

(2)实现求最大值的函数如下:

templateListNode*List:

:

Max(){

//在单链表中进行一趟检测,找出具有最大值的结点地址,如果表空,返回指针NULL

if(first->link==NULL)returnNULL;//空表,返回指针NULL

ListNode*pmax=first->link,p=first->link->link;

//假定第一个结点中数据具有最大值

while(p!

=NULL){//循环,下一个结点存在

if(p->data>pmax->data)pmax=p;//指针pmax记忆当前找到的具最大值结点

p=p->li

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 少儿英语

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1