线性表 教案.docx

上传人:b****0 文档编号:12595061 上传时间:2023-04-20 格式:DOCX 页数:16 大小:69.01KB
下载 相关 举报
线性表 教案.docx_第1页
第1页 / 共16页
线性表 教案.docx_第2页
第2页 / 共16页
线性表 教案.docx_第3页
第3页 / 共16页
线性表 教案.docx_第4页
第4页 / 共16页
线性表 教案.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

线性表 教案.docx

《线性表 教案.docx》由会员分享,可在线阅读,更多相关《线性表 教案.docx(16页珍藏版)》请在冰豆网上搜索。

线性表 教案.docx

线性表教案

线性表

【教学目的】:

1、了解数据结构的概念

2、掌握时间复杂度的概念和计算方法

【教学方法】:

理论教学

【教学课时】:

2课时(复习)

【教学内容】:

一、基础知识和算法

线性表及其特点

线性表是n个数据元素的有限序列。

线性结构的特点:

①“第一个”②“最后一个”③前驱④后继。

1.顺序表——线性表的顺序存储结构

特点

a)逻辑上相邻的元素在物理位置上相邻。

b)随机访问。

类型定义

简而言之,“数组+长度”。

constintMAXSIZE=线性表最大长度;

typedefstruct{

DataTypeelem[MAXSIZE];

intlength;

 

}SqList;

注:

a)SqList为类型名,可换用其他写法。

b)DataType是数据元素的类型,根据需要确定。

c)MAXSIZE根据需要确定。

constintMAXSIZE=64;

d)课本上的SqList类型可在需要时增加存储空间,在上面这种定义下不可以。

(这样做避免了动态内存分配,明显减少了算法的复杂程度,容易理解。

而且,原来Pascal版本的《数据结构》(严蔚敏)就是这样做的。

e)课本上的SqList类型定义中listsize表示已经分配的空间大小(容纳数据元素的个数)。

当插入元素而遇到L.length==L.listsize时,用realloc(L.elem,L.listsize+增量)重新分配内存,而realloc()函数在必要的时候自动复制原来的元素到新分配的空间中。

基本形态

顺序表空

条件L.length==0

不允许删除操作

顺序表满

条件L.length==MAXSIZE

不允许插入操作

不空也不满

可以插入,删除

基本算法——遍历

顺序访问所有元素

for(i=0;i

visit(L.elem[i]);

查找元素x

for(i=0;i

if(L.elem[i]==x)break;

if(i

找到;

else

未找到;

插入算法ListInsert(&L,i,x)

前提:

表不满

合理的插入范围:

1≤i≤L.length+1

注:

位序i在C/C++中对应于下标i-1。

步骤

第i至最后所有元素后移一个元素

在第i个位置插入元素x

表长增1

算法

boolListInsert(SqList&L,inti,DataTypex){

if(L.length==MAXSIZE||i<1||i>L.length+1)returnfalse;//失败

//元素后移

for(j=L.length-1;j>=i-1;j--)//这里j为下标,从L.length-1到i-1

L.elem[j+1]=L.elem[j];//若作为位序,有如何修改?

//插入x

L.elem[i-1]=x;

//表长增1

L.length++;

returntrue;//插入成功

}

删除算法ListDelete(&L,i,&x)

前提:

表非空

合理的删除范围:

1≤i≤L.length

步骤

取出第i个元素

第i个元素之后的元素向前移动一个位置

表长减1

算法

boolListDelete(SqList&L,inti,DataType&x)

{

if(L.length==0||i<1||i>L.length)returnfalse;//失败

x=L.elem[i-1];

for(j=i;j

L.elem[j-1]=L.elem[j];

L.length--;

returntrue;//删除成功

}

算法分析

表2.1顺序表插入和删除算法的分析

插入

删除

基本操作

平均移动次数

移动元素

移动元素

时间复杂度

O(n)

O(n)

尾端操作

插入第n+1个元素,不移动

删除第n个元素,不移动

插入、删除需移动大量元素O(n);但在尾端插入、删除效率高O

(1)。

其他算法

InitList(&L),ClearList(&L)

L.length=0;

ListEmpty(L)

returnL.length==0;

ListLength(L)

returnL.length;

GetElem(L,i,&e)

e=L.elem[i-1];

2.单链表——线性表的链式存储结构之一

概念

线性链表,单链表,结点;数据域,指针域;头指针,头结点。

特点

用指针表示数据之间的逻辑关系(逻辑相邻的元素物理位置不一定相邻)。

类型定义

简而言之,“数据+指针”。

typedefstructLNode{

DataTypedata;

structLNode*next;

}LNode,*LinkList;

基本形态

带头结点的单链表的基本形态有:

单链表空

条件:

L->next==0

单链表不空

条件:

L->next!

=0

 

基本算法(遍历)

顺序访问所有元素

借助指针,“顺藤摸瓜”(沿着链表访问结点)。

p=L->next;//注意起始位置的考虑

while(p!

=NULL){//判表尾,另外(p!

=0)或(p)均可

visit(p->data);//访问:

可以换成各种操作

p=p->next;//指针沿着链表向后移动

}

例:

打印单链表中的数据。

voidPrintLinkList(LinkListL)

{

p=L->next;

while(p!

=NULL){

print(p->data);//访问:

打印数据域

p=p->next;

}

}

查找元素x

//在单链表L中查找元素x

//若找到,返回指向该结点的指针;否则返回空指针

LinkListFind(LinkListL,DataTypex)

{

p=L->next;

while(p!

=NULL){

if(p->data==x)returnp;//找到x

p=p->next;

}

returnNULL;//未找到

}

//在单链表L中查找元素x

//若找到,返回该元素的位序;否则返回0

intFind(LinkListL,DataTypex)

{

p=L->next;j=1;

while(p!

=NULL){

if(p->data==x)returnj;//找到x

p=p->next;j++;//计数器随指针改变

}

return0;//未找到

}

前一个算法的另一种写法:

p=L->next;

while(p&&p->data!

=x)

p=p->next;

if(p&&p->data==x)returnp;

elsereturn0;

或者

p=L->next;

while(p&&p->data!

=x)p=p->next;

returnp;//为什么

查找第i个元素

LinkListGet(LinkListL,inti)

{

p=L->next;j=1;

while(p&&j

p=p->next;j++;

}

if(p&&j==i)returnp;

elsereturn0;

}

查找第i-1个元素

p=L;j=0;

while(p&&j

p=p->next;j++;

}

if(p&&j==i-1)returnp;

elsereturn0;

插入算法ListInsert(&L,i,x)

技巧:

画图辅助分析。

思路:

先查找第i-1个元素

若找到,在其后插入新结点

boolListInsert(LinkList&L,inti,DataTypex)

{

//查找第i-1个元素p

p=L;j=0;

while(p&&j

p=p->next;j++;

}

//若找到,在p后插入x

if(p&&j==i-1){

s=(LinkList)malloc(sizeof(LNode));

s->data=x;

s->next=p->next;//①

p->next=s;//②

returntrue;//插入成功

}

else

returnfalse;//插入失败

}

注意:

a)要让p指向第i-1个而不是第i个元素(否则,不容易找到前驱以便插入)。

b)能够插入的条件:

p&&j==i-1。

即使第i个元素不存在,只要存在第i-1个元素,仍然可以插入第i个元素。

c)新建结点时需要动态分配内存。

s=(LinkList)malloc(sizeof(LNode));

若检查是否分配成功,可用

if(s==NULL)exit

(1);//分配失败则终止程序

d)完成插入的步骤:

①②。

技巧:

先修改新结点的指针域。

删除算法ListDelete(&L,i,&x)

思路:

先查找第i-1个元素

若找到且其后存在第i个元素,则用x返回数据,并删除之

boolListDelete(LinkList&L,inti,int&x)

{

//查找第i-1个元素p

p=L;j=0;

while(p&&j

p=p->next;j++;

}

//若存在第i个元素,则用x返回数据,并删除之

if(p&&j==i-1&&p->next){//可以删除

s=p->next;//①

p->next=s->next;//②

x=s->data;

free(s);

returntrue;

}

else

returnfalse;

}

注意:

a)要求p找到第i-1个而非第i个元素。

为什么?

b)能够进行删除的条件:

p&&j==i-1&&p->next。

条件中的p->next就是要保证第i个元素存在,否则无法删除。

若写成p->next&&j==i-1也不妥,因为此时(循环结束时)可能有p==NULL,所以必须先确定p不空。

技巧:

将条件中的“大前提”放在前面。

该条件也不可以写成p->next&&p&&j==i-1,因为先有p!

=0才有p->next,上式颠倒了这一关系。

c)释放结点的方法。

free(s);

d)完成删除的步骤:

①②。

建立链表的两种方法

思路:

建立空表(头结点);

依次插入数据结点(每次插入表尾得(a1,a2,…,an),每次插入表头得(an,…,a2,a1))。

顺序建表

voidCreateLinkList(LinkList&L,intn)

{

//建立空表

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

L->next=NULL;//空表

p=L;//用p指向表尾

//插入元素

for(i=0;i

scanf(x);

s=(LinkList)malloc(sizeof(LNode));

s->data=x;

//插入表尾

s->next=p->next;

p->next=s;

p=s;//新的表尾

}

}

逆序建表

voidCreateLinkList(LinkList&L,intn)

{

//建立空表

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

L->next=NULL;//空表

//插入元素

for(i=0;i

scanf(x);

s=(LinkList)malloc(sizeof(LNode));

s->data=x;

//插入表头

s->next=L->next;

L->next=s;

}

}

3.循环链表

特点

最后一个结点的指针指向头结点。

类型定义

同单链表。

基本形态

空表:

L->next==L。

非空表。

与单链表的联系

判断表尾的方法不同:

单链表用p==NULL;循环链表用p==L。

其余操作相同。

4.双向循环链表

特点

一个结点包含指向后继(next)和指向前驱(prior)两个指针,两个方向又分别构成循环链表。

类型定义

typedefstructDuLNode{

DataTypedata;

structDuLNode*prior,*next;//两个指针

}DuLNode,*DuLinkList;

基本形态

空表:

用后向指针判断L->next==L,或者用前向指针判断L->prior==L。

非空表。

与单链表和循环链表的联系

最大不同:

前驱容易求得,可以向前遍历。

判断表尾的方法与循环链表相同:

p==L。

插入和删除时需要修改两个方向的指针。

插入和删除

需要修改两个方向的指针。

例如:

(见下表)

表2.2双向循环链表的插入和删除

p之后插入s

p之前插入s

删除p之后继s

删除p

s->next=p->next;

p->next=s;

s->prior=p;

s->next->prior=s;

s->prior=p->prior;

p->prior=s;

s->next=p;

s->prior->next=s;

s=p->next;

p->next=s->next;

p->next->prior=p;

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

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

5.顺序表与单链表的比较

表2.3顺序表和单链表的比较

顺序表

单链表

以地址相邻表示关系

用指针表示关系

随机访问,取元素O

(1)

顺序访问,取元素O(n)

插入、删除需要移动元素O(n)

插入、删除不用移动元素O(n)(用于查找位置)

总结:

需要反复插入、删除,宜采用链表;反复提取,很少插入、删除,宜采用顺序表。

二、习题

2.1将顺序表中的元素反转顺序。

2.2在非递减有序的顺序表中插入元素x,并保持有序。

2.3删除顺序表中所有等于x的元素。

2.4编写算法实现顺序表元素唯一化(即使顺序表中重复的元素只保留一个),给出算法的时间复杂度。

2.5非递减有序的顺序表元素唯一化(参见习题2.4),要求算法的时间复杂度为O(n)。

2.6将单链表就地逆置,即不另外开辟结点空间,而将链表元素翻转顺序。

2.7采用插入法将单链表中的元素排序。

2.8采用选择法将单链表中的元素排序。

2.9将两个非递减有序的单链表归并成一个,仍并保持非递减有序。

 

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

当前位置:首页 > 求职职场 > 笔试

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

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