第2章 -1(线性表)

合集下载

第二章 线性表

第二章 线性表

(7)已知顺序表L中的元素有序递增,设计算法将元素x插入到L 种,并依旧保持其有序递增;设计一个高效的算法,删除顺序表 中所有值为x的元素,要求空间复杂度为O(1)。(基于顺序表基本 操作的运算) (8)(2010年13分)设将n(n>1)个整数存放到一维数组R中。试 设计一个在时间和空间两方面尽可能有效的算法,将R中保有的 序列循环左移P(0<p< n)个位置,即将R中的数据由(X0 X1 ……Xn-1)变换为(Xp Xp+1 ……Xn-1 X0 X1……Xp-1) 要求: (1)给出算法的基本设计思想。 (2)根据设计思想,采用C或C++或JAVA语言描述算法,关键之处 给出注释。 (3)说明你所设计算法的时间复杂度和空间复杂度
2 3 4 5 6
30 60 20 40
6 -1 3 1
h
10
20Βιβλιοθήκη 304050
60∧
8、例题: (1)链表不具有的特点是( )。 A.可随机访问任一元素 B.插入删除不需要移动元素 C.不必事先估计存储空间 D.所需空间与线性表长度成正比 (2)在具有n个结点的单链表中插入一个新结点并使链表仍然有 序的时间复杂度是( )。 A. O(1) B. O(n) C. O(nlog2n) D. O(n2) (3)对于由n个元素组成的线性表,创建一个有序单链表的时间 复杂度是( )。 A. O(1) B. O(n) C. O(nlog2n) D. O(n2)
(4)设A是一个线性表,采用顺序存储结构。在等概率情况下, 平均插入一个元素需要移动多少个元素?若元素插在ai和ai+1之 间的概率为(n-i)/n(n-1)/2,则平均插入一个元素需要移动多少 个元素? (5)以顺序表作为存储结构,实现线性表的就地逆置;判断回 文;设计一个时间复杂度为O(n)的算法,将顺序表中所有元素循 环左移k位;设计一个时间复杂度为O (n)的算法,将顺序表中所 有元素循环右移k位;(基于逆置操作的运算) (6)将顺序表中的元素调整为左右两部分,左边元素为奇数, 右边元素为偶数,要求算法的时间复杂度为O (n);将顺序表A拆 分为B 和C,其中B中的元素小于0,C中的元素大于0;将有序表A和 有序表B合并为C,合并后C依然是有序的。(基于对顺序表的拆分 和合并操作的运算)

线性表

线性表

举例:
La=(34,89,765,12,90,-34,22) 数据元素类型为int。 Ls=(Hello,World, China, Welcome) 数据元素类型为 string。 Lb=(book1,book2,...,book100) 数据元素类型为下列所示的结 构类型: struct bookinfo { int No; //图书编号 char *name; //图书名称 char *auther; //作者名称 ...; };
素的方法被称为随机存取法,使用这种存取方法的存储结构被
称为随机存储结构。
在C语言中,实现线性表的顺序存储结构的类型定义
typedef int ElemType; //定义顺序表中元素的类型 #define INITSIZE 100 //顺序表存储空间初始分配量 #define LISTINCREMENT 10 //线性表存储空间的分配增量 typedef struct { ElemType *data; int length; //存储空间的基地址 //线性表的当前长度
说明:
1. 某数据结构上的基本运算,不是它的全部运算,而是一些 常用的基本的运算,而每一个基本运算在实现时也可能根据不 同的存储结构派生出一系列相关的运算来, 没有必要全部定义 出它的运算集。掌握了某一数据结构上的基本运算后,其它的 运算可以通过基本运算来实现,也可以直接去实现。 2. 在上面各操作中定义的线性表L仅仅是一个抽象在逻辑结 构层次的线性表,尚未涉及到它的存储结构,因此每个操作在 逻辑结构层次上尚不能用具体的某种程序语言写出具体的算法, 而算法的实现只有在存储结构确立之后。
4. 求顺序表的长度 int getlen(sqlist L) { return (L.length); } 5. 判断顺序表是否为空 int listempty(sqlist L) { if (L.length==0) return 1; else return 0; }

线性表练习题答案

线性表练习题答案

第2章线性表练习题答案一、填空1. 向一个长度为n的向量的第i个元素(1≤i≤n+1)之前插入一个元素时,需向后移动n-i+1 个元素。

2. 向一个长度为n的向量中删除第i个元素(1≤i≤n)时,需向前移动n-i 个元素。

3. 在顺序表中访问任意一结点的时间复杂度均为O(1),因此,顺序表也称为随机存取的数据结构。

4. 在单链表中,除了首元结点外,任一结点的存储位置由其直接前驱结点的链域的值指示。

5.在n个结点的单链表中要删除已知结点*p,需找到它的前驱结点的地址,其时间复杂度为O(n)。

二、判断正误(×)1. 链表的每个结点中都恰好包含一个指针。

答:错误。

链表中的结点可含多个指针域,分别存放多个指针。

例如,双向链表中的结点可以含有两个指针域,分别存放指向其直接前趋和直接后继结点的指针。

(×)2. 链表的物理存储结构具有同链表一样的顺序。

错,链表的存储结构特点是无序,而链表的示意图有序。

(×)3. 链表的删除算法很简单,因为当删除链中某个结点后,计算机会自动地将后续的各个单元向前移动。

错,链表的结点不会移动,只是指针内容改变。

(×)4. 线性表的每个结点只能是一个简单类型,而链表的每个结点可以是一个复杂类型。

错,混淆了逻辑结构与物理结构,链表也是线性表!且即使是顺序表,也能存放记录型数据。

(×)5. 顺序表结构适宜于进行顺序存取,而链表适宜于进行随机存取。

错,正好说反了。

顺序表才适合随机存取,链表恰恰适于“顺藤摸瓜”(×)6. 顺序存储方式的优点是存储密度大,且插入、删除运算效率高。

错,前一半正确,但后一半说法错误,那是链式存储的优点。

顺序存储方式插入、删除运算效率较低,在表长为n的顺序表中,插入和删除一个数据元素,平均需移动表长一半个数的数据元素。

(×)7. 线性表在物理存储空间中也一定是连续的。

错,线性表有两种存储方式,顺序存储和链式存储。

线性表

线性表

2.1 线性表的类型定义
例3:下图为10个个学生的成绩表,它也是一个 线性表,该线性表的数据元素类型为结构体类型。
2.1 线性表的类型定义
从以上例子可看出线性表的逻辑特征是: 在非空的线性表中,有且仅有一个被称作 “第一个”的数据元素a1,它没有直接前趋, 而仅有一个直接后继a2; 有且仅有一个被称作“最后一个”的数据元 素an,它没有直接后继,而仅有一个直接前 趋 a n-1; 其余的数据元素ai(2≦i≦n-1)都有且仅有一个 直接前趋a i-1和一个直接后继a i+1。 线性表是一种典型的线性结构。
2.2 线性表的顺序表示和实现
#define MAXNUM 100 Elemtype List1[MAXNUM] ; /*定义线性表L1*/ int length1;
Elemtype List2[MAXNUM] ; /*定义线性表L1*/ int length2;
Elemtype List3[MAXNUM] ; /*定义线性表L1*/ int length3;
2.2 线性表的顺序表示和实现
而只需要将数组和表长封装在一个结构体中,然 后定义三个结构体变量即可: struct L_list { Elemtype List[MAXNUM]; int length; }; struct L_list L1, L2, L3; /*定义三个线性表L1,L2,L3*/
2.1 线性表的类型定义
例1:26个英文字母组成的字母表 (A,B,C、…、Z) 例2:某公司2000年每月产值表(单位:万元) (400,420,500,…,600,650) 是一个长度为12的线性表。

上述两例中的每一个数据元素都是不可分割的, 在一些复杂的线性表中,每一个数据元素又可 以由若干个数据项组成。

数据结构李春葆 第2章 线性表

数据结构李春葆 第2章  线性表

2.2.1 线性表的顺序存储—顺序表
线性表的顺序存储结构:把线性表中的所有元素按照 其逻辑顺序依次存储到从计算机存储器中指定存储位臵开 始的一块连续的存储空间中。 这样,线性表中第一个元素的存储位臵就是指定的存储 位臵,第i+1个元素(1≤i≤n-1)的存储位臵紧接在第i个元 素的存储位臵的后面。 线性表 逻辑结构 顺序表 存储结构
回true,否则返回false。
bool ListEmpty(SqList *L) {
return(L->length==0);
}
本算法的时间复杂度为O(1)。
(4)求线性表的长度ListLength(L)
该运算返回顺序表 L 的长度。实际上只需返回 length成员 的值即可。
int ListLength(SqList *L)
( 3 )判线性表是否为空表 ListEmpty(L) :若 L 为空表, 则返回真,否则返回假。 ( 4 )求线性表的长度 ListLength(L) :返回 L 中元素个数。 ( 5)输出线性表 DispList(L): 当线性表 L不为空时,顺序 显示L中各节点的值域。 (6)求线性表L中指定位臵的某个数据元素 GetElem(L,i,&e) :用 e 返回 L 中第 i ( 1≤i≤ListLength(L) )个 元素的值。
void unionList(List LA,List LB,List &LC) { int lena,i; ElemType e; InitList(LC); for (i=1;i<=ListLength(LA);i++) //将LA的所有元素插入到Lc中 { GetElem(LA,i,e); ListInsert(LC,i,e); } lena=ListLength(LA); //求线性表LA的长度 for (i=1;i<=ListLength(LB);i++) { GetElem(LB,i,e); //取LB中第i个数据元素赋给e if (!LocateElem(LA,e)) //LA中不存在和e相同者,插入到LC中 ListInsert(LC,++lena,e); } }

数据结构 线性表

数据结构 线性表

(9) Status NextElem_Sq(SqList L, ElemType cur_e, ElemaType &next_e)
//若cur_e是线性表L的元素且不是最后一个,返回它的后继 { for (i=0; i<L.length-1; i++) if (cur_e==L.elem[i]) { next_e=L.elem[i+1]; return OK; } return ERROR; }//NextElem_Sq O(n)
抽象数据类型 唯 一 数据的逻辑结构 确 操作的定义 定
集合 *
线性表
特殊线性表 扩展线性表
线性结构
树形结构 图形结构
灵 活 数据的存储结构 操作的实现 设 计
顺序存储 链式存储 散列(哈希)存储
数据的基本操作:针对结构、针对元素、针对状态
数据结构---第二章 线性表 1
第二章 线性表
2.1 2.2 2.3 2.4
数据结构---第二章 线性表
9
2.2 线性表的顺序存储结构(顺序表)
起始地址为b、最多可容纳maxlen个元素的线性表
下标 存储地址
0
1
b b+c
b+(i-1)c
a1 a2
ai
c个存储单元
i-1
LOC(ai)=LOC(a1)+(i-1)c LOC(ai)=LOC(ai-1)+c
n-1
b+(n-1)c
n-1
int LocateElem_Sq(SqList L, ElemType e, (7) Status (*compare)(ElemType,ElemType) ) //在线性表L中查找第1个值与e满足 //compare()的元素的位序 { for (i=0; i<L.length; i++) L.elem[i]==e if ( (*compare)(L.elem[i],e) ) return i+1; return 0 ; //作为未找到的特殊标记 } // LocateElem_Sq O(n) P25-2.6

《数据结构》课程课件第二章线性表

《数据结构》课程课件第二章线性表

Step2:数据域赋值
插入后: Step3:插入(连接)
X q
(1)式和(2)式的顺序颠倒,可以吗?
4、插入元素(在第i个元素之前插入元素e)
为什么时间复杂度不再是O(1)?
第i-1个元素
第i个元素
p
s
新插入元素
5、删除p所指元素的后继元素
P
删除前:
P->next P->next->next
删除:
五、线性表ADT的应用举例
Void mergelist(list La,list Lb,list &Lc)
{ //已知线性表La和Lb中的数据元素按值非递减排列
//归并La和Lb得到新的线性表Lc,Lc中的元素也按值非递减排列
例: 将两个各有n个元素的有序表归并成一个有序表, 其最小的比较次数是( )。 A、n B、2n-1 C、2n D、n-1
三、线性表的ADT
四、线性表的分类
五、线性表ADT的应用举例
例1:已知有线性表L,要求删除所有X的出现
五、线性表ADT的应用举例
例2: 已知有两个分别有序的线性表(从小到大),要 求合并两个线性表,且合并后仍然有序。——归并 方法1: 合并,再排序O((m+n)2)
方法2: 归并,利用分别有序的特点O((m+n))
二、线性表上常见的运算
8、删除 Delete(L,i):删除线性表的第i个元素 删除前 a1 a2 … ai-1 ai ai+1 … an 删除后 a1 a2 … ai-1 ai+1 … an 9、判断是否为空 Empty(L):线性表空,则返回TRUE, 否则FALSE 10、输出线性表 Print(L):输出线性表的各个元素 11、其它操作 复制、分解、合并、分类等

第2章线性表辅导

第2章线性表辅导

第2章线性表辅导本章通过实例给出线性表的定义,介绍线性表的逻辑结构、顺序存储结构和链式存储结构,讨论线性表在两种不同存储结构下对应的顺序表和链表的相关操作,介绍线性表的简单应用。

通过本章学习,要求同学们:1.掌握线性表的定义和逻辑结构。

2.掌握线性表的顺序存储结构的有关概念,能利用C语言的数组和指针实现对顺序表的相关操作。

3.掌握线性表的链式存储结构的有关概念,并重点掌握单向链表的特点和访问方式,能利用C语言的结构变量和指向结构体的指针实现对链表的相关操作。

4.正确理解线性表两种存储结构各自的特点和应用场合,能利用所学知识和按照相关要求设计算法、编制程序,利用线性表解决简单的应用问题。

一、本章知识点1. 线性表的定义及特点线性表是一种最简单、最常用的一种数据结构。

线性表中的元素存在着一对一的相互关系。

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

其中n为数据元素的个数,定义为数据表的长度。

当n为零时的表称为空表。

当n>0时,一般将线性表记为:(a1,a2,…a i-1,a i,…a n),其中a i(i=1,2,3,…,n)是属于某个数据对象的元素,由线性表的定义,若线性表至少包含2个元素,则线性表中的数据元素之间存在以下关系:1.表中存在称作“第一个”的元素,例如上表中的a1,存在称作“最后一个”的数据元素,例如上表中的a n。

2.表中第一个元素a1前面没有元素和它相邻,称它没有直接前驱,它后面有且只有一个元素a2与它相邻,称它有且只有一个直接后继。

而表中“最后一个”元素a n有且只有一个直接前驱a n-1,没有直接后继。

3.除“第一个”元素和“最后一个”元素外,其它每个元素均有且只有一个直接前驱和一个直接后继。

2.线性表的顺序存储结构用一组地址连续的存储单元依次存放线性表的数据元素,该结构的特点是逻辑上相邻的数据元素在物理上也相邻,可以随机访问,一对一的关系。

用顺序存储结构存储的线性表称为顺序表3.顺序表的操作(1)插入操作插入操作的算法步骤为:从a n开始逐次将a n,a n-1.,…,a i向后平移一个存储位置,然后将x存入到a[i]中。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

例:线性结构的C++语言描述:
const int maxsize=maxlen;
Class SequenList { public:
elemtype a[maxsize];
int len; int Length(sequenlist L); void Insert(sequenlist &L, elemtype x,int i); void Dele(sequenlist &L, int i);
Data: 一个线性表L定义为L=(a1,a2,…,an),当L=( )时定义 为一个空表 operation:
void
int
setnull(&L) //将线性表L置成空表
Length(L) //求给定线性表L的长度
elemtype Get(L,i) //取线性表L第i个位置上的元素
elemtype Prior(L,x) //求线性表L中元素值为X的直接
3. 删除运算Delete(&L,i) (见图2-4) void sequenlist::Delete(sequenlist &L,int i)
{ int j; if((i<1)||(i>L.len))
cout<<”位置不正确!”<<endl;
else { for( j=i+1; j<=L.len; j++) L.a[j-1] = L.a[j]; L.len - - ; } } //元素前移 //表长度减1
void Setnull(sequenlist &L);
int Locate(sequenlist L, elemtype x); elemtype Get(sequenlist L, int i);
};
存储地址 b b+d … b+(i-1)×d … b+(n-1)×d
内存排列
位置序号 0 1 2 … i … n … maxlen-1
该算法的时间复杂度为O(1)。
5. 定位算法Locate(L,x)
int sequenlist::Locate(sequenlist L, elemtype x)
{ int j=1; while(j<=L.len)&&(L.a[j]!=x) j++; if(j<=L.len) return j;
else return 0;
序号 0 1 2 3 … i-1 i i+1 … n … maxsize-1
内容
序号 0
内容
a1 a2 a3 … ai-1 ai ai+1 … an …
1 2 3 … i-1 i i+1 … n-1 … maxsize-1
a1 a2 a3 … ai-1 ai+1 ai+2 … an …
删除前
删除后
} 该算法的时间复杂度为O(n)。
6. 取元素Get(L,i) elemtype sequenlist::Get(sequenlist L,int i) { if(i<1)||(i>L.len) return NULL; else return L.a[i]; }
该算法的时间复杂度为O(1)。
2.2.3 顺序表存储空间的动态分配 若将前面线性表的顺序存储结构类型中的数组形式 改为指针形式,则得到动态分配形式如下: struct sequenlist
L.len=0;
}
linear_list=(A,R) 其中 A={ai ∣1≤i≤n,n≥0,ai∈elemtype} R={r}
r={<ai,ai+1> ∣1≤i≤n-1}
对应的逻辑结构图如图2-1所示。
a1 a2
……
an
图 2-1 线性表逻辑结构示意图
2.1.2 线性表的运算
常见线性表的运算有: 1.置空表 SETNULL(&L)将线性表L置成空表 2. 求长度 LENGTH(L) 求给定线性表L的长度 3. 取元素 GET(L,i) 若1≤i≤length(L),则取第I
{
elemtype *a; int len; …… };
在此时,只有线性表置空表算法需要修改,其它算 法都与静态分配相同。这时的置空表算法应改为: void sequenlist :: setnull(sequenlist &L) { L.a=new elemtype[maxsize]; //动态申请存储单元 if(L.a==NULL) exit(1); //申请不成功
[
i 1
n 1
1 n 1
(n i 1)] =
故时间复杂度为O(n)。
n 2
n 1 同理,可推出删除运算的平均移动次数为 , 2
故时间复杂度为O(n)。
4. 置空表setnull(&L)
void sequenlist::setnull(sequenlist &L)
{ L.len=0; }
a1 a2 … ai … an …
图 2-2 顺序存储结构示意图
2.2.2 顺序表运算
1.求顺序表的长度length(L) int sequenlist::length(sequenlist L) { return L.len; } 该算法的语句频度为1,时间复杂度为0(1)。
2.插入运算Insert( &L,x,i) (见图2-3) void sequenlist::Insert(sequenlist &L,elemtype x,int i) { int j; if(L.len>=maxsize-1) cout<<”溢出”<<endl; else if ((i<1)||(i>L.len+1) cout<<”位置不正确!”<<endl; else { for( j=L.len; j>=i; j--) L.a[j+1] = L.a[j]; //元素后移 L.a[i] = x; //插入元素 L.len ++; //表长度增加1 } }
元素
END Linearlist
例 2-1 假设线性表 L=(23,56,89,76,18),i=3,x=56,y=88, 则 对L的一组操作及结果如下: Length(L); Get(L,i) Prior(L,x) //所得结果为5 //所得结果为89 //所得结果为23
Next(L,x)
Locate(L,x)
前趋 elemtype Next(L,x) //求线性表L中元素值为X的直接
后继
int Locate(L,x) //在线性表L中查找值为X的元素 位置 void Insert(&L,x,i) //在线性表L中第i个位置上插入 值为X的元素
void
Delete(&L,i) //删除线性表L中第i个位置上的
为X的元素位置,若有多个值为X,则以第一个为
准,若没有,位置为0。 7.插入 INSERT(&L,X,i)在线性表L中第i个位 置上插入值为X的元素。 8.删除 DELETE(&L,i) 删除线性表L中第i个位
置上的元素。
2.1.3线性表的抽象数据类型描述 上述这些操作可用抽象数据类型描述为:
ADT Linearlist is
图 2-4 顺序表中删除元素前后状态
插入算法花费的时间,主要在于循环中元素的后 移(其它语句花费的时间可以省去),即从插入位置 到最后位置的所有元素都要后移一位,使空出的位置 插入元素值x。但是,插入的位置是不固定的,当插入 位置i=1时,全部元素都得移动,需n次移动,当i=n+ 1时,不需移动元素,故在 i 位置插入时移动次数为 ni+1,假设在每个位置插入的概率相等为 1 ,则平均 n 1 移动元素的次数为
从线性表的定义可以看出线性表的特征: ⑴ 有且仅有一个开始结点(表头结点)a1,它没有直
接前驱,只有一个直接后继;
⑵ 有且仅有一个终端结点(表尾结点)an,它没有直接 后继,只有一个直接前驱; ⑶ 其它结点都有一个直接前驱和直接后继; ⑷ 元素之间为一对一的线性关系。
线性表是一种典型的线性结构,用二元组表示为:
//所得结果为89
//所得结果为2
Insert(&L,y,i) //所得结果为(23,56,88,89,76,18) Delete(&L,i+1) //所得结果为(23,56,88,76,18)
2.2线性表的顺序存储结构 2.2.1 顺序表结构:
⑴线性表的顺序存储结构,也称为顺序表。 ⑵把线性表的各个数据元素依次存储在一组连续的存储单元里。 ⑶表中相邻的元素Ai和Ai+1存储位置也相邻。 ⑷使用数组来描述数据结构中的顺序存储结构。 ⑸顺序结构的线性表有随机存取第i个元素,插入,删除等 基本操作。
序号 0 1 2 3 … i-1 i i+1 … n … maxsize-1
内容
序号 0
内容
a1 a2 a3 … ai-1 ai ai+1 … an …
1 2 3 … i-1 i i+1 … n … maxsize-1
a1 a2 a3 … ai-1 x ai … an-1 an
插入前
插入后
图 2-3 顺序表中插入元素前后状态
第2章
线性表
数据结构(C++描述)
目录
2.1 线性表的定义及其运算
2.2线性表的顺序存储结构
2.3 线性表的链式存贮结构
结束放演
2.1 线性表的定义及其运算 2.1.1线性表的定义 1. 线性表的定义:
线性表是n(n≥0)个数据元素a1,a2,…an组成的有限序列。 ⑴n 称为数据元素的个数或线NULL。
相关文档
最新文档