第02章 线性表
DS02线性表习题参考解答

第2章线性表习题参考解答一、简答题1.试描述头指针、头结点、开始结点的区别、并说明头指针和头结点的作用。
【答】头指针:是指向链表中的第一个结点的指针。
头结点:在开始结点之前附加上的一个结点。
开始结点:链表的第一个结点。
头指针是一个指向地址的变量,用于表示一个链表的开始。
引入头结点可以更加方便的进行链表是否为空的判断,同时方便了插入和删除结点。
开始结点用于存储链表的第一个数据元素。
2.何时选用顺序表、何时选用链表作为线性表的存储结构为宜?【答】顺序表中查找元素、获取表长非常容易,但是,要插入或者删除一个元素却需要移动大量的元素;相反,链表中却是方便插入或者删除元素,在查找元素的是,需要进行遍历。
因此,当所涉及的问题常常进行查找等操作,而插入、删除相对较少的是,适合采用顺序表;当常常需要插入、删除的时候,适合采用链表。
3.为什么在单循环链表中设置尾指针比设置头指针更好?【答】在单循环链表中,设置尾指针,可以更方便的判断链表是否为空。
4.在单链表、双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?【答】本题分三种情况讨论:1、单链表:当知道指针p指向某结点时,能够根据该指针找到其直接后继,但是不知道头指针,因此不能找到该结点的直接前趋,因此,无法删除该结点。
2、双链表:根据指针p可以找到该结点的直接前趋和直接后继,因此,能够删除该结点。
3、单循环链表:和双链表类似,根据指针p也可以找到该结点的直接前趋和直接后继,因此,也可以删除该结点。
5.下述算法的功能是什么?LinkList Demo(LinkList *L) /* L是无头结点单链表*/{LNode *Q,*P;if(L&&L->next){Q=L;L=L->next;P=L;while (P->next) P=P->next;P->next=Q; Q->next=NULL;}return L;} /* Demo */【答】将原来的第一个结点变成末尾结点,原来的第二个结点变成链表的第一个结点。
线性表

举例:
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; }
02331自考数据结构 第二章 线性表

return ;
}
if ( L -> length >= ListSize ){
printf (" overflow ");
return ;
}
for ( j - L -> length -1; j >= i -1; j --)
L ->data [ j +1]= L -> data [ j ]; //从最后一个元素开始逐一后移
线性表的基本运算
上述运算仅仅是线性表的基本运算,不是其全部运 算。因为对不同问题的线性表,所需要的运算可能不同。 因此,对于实际问题中涉及其他更为复杂的运算,可用 基本运算的组合来实现。
线性表的基本运算
【例2.1】假设有两个线性表 LA 和 LB 分别表示两个 集合 A 和 B ,现要求一个新集合 A = A∪B 。
线性表的逻辑定义
数据元素“一个接一个的排列”的关系叫做 线性关系,线性关系的特点是“一对一”,在计 算机领域用“线性表”来描述这种关系。另外, 在一个线性表中数据元素的类型是相同的,或者 说线性表是由同一类型的数据元素构成的,如学 生情况信息表是一个线性表,表中数据元素的类 型为学生类型;一个字符串也是一个线性表:表 中数据元素的类型为字符型等等。
,
a2
i
,…,
ai-1
,
a.aii++1.1 , .…,
an
)
an
线性表n的-1逻辑结an构和存储结构都发…生了相应的变化, 与插入运算相反,插…入是向后移动元素,而删除运算则
是向前移M动AX元-1 素,除非i=n 时直接删除终端元素,不需移
动元素。
删除前
删除后
线性表

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章--线性表PPT课件

一个(尾)结点。
.
4
a1,a2,…ai-1都是ai(2≦i≦n)的前驱,其中ai-1是ai的直接 前驱; ai+1,ai+2,…an都是ai(1≦i ≦n-1)的后继,其中ai+1是ai的 直接后继。
2.1.2 线性表的逻辑结构
线性表中的数据元素ai所代表的具体含义随具体应 用的不同而不同,在线性表的定义中,只不过是一个抽 象的表示符号。
以下将对几种主要的操作进行讨论。
1 顺序线性表初始化
Status Init_SqList( SqList *L )
{ L->elem_array=( ElemType * )malloc(MAX_SIZE*sizeof( ElemType ) ) ;
if ( !L -> elem_array ) return ERROR ;
ListInsert ( L, i, &e )
初始条件:线性表L已存在,1≦i≦ListLength(L) ;
操作结果:在线性表L中的第i个位置插入元素e;
…
.
8
} ADT List
2.2 线性表的顺序存储
2.2.1 线性表的顺序存储结构
顺序存储 :把线性表的结点按逻辑顺序依次存放在 一组地址连续的存储单元里。用这种方法存储的线性表 简称顺序表。
在具体的机器环境下:设线性表的每个元素需占用L 个存储单元,以所占的第一个单元的存储地址作为数据元素 的存储位置。则线性表中第i+1个数据元素的存储位置 LOC(ai+1)和第i个数据元素的存储位置LOC(ai)之间满足 下列关系:
LOC(ai+1)=LOC(ai)+L
线性表的第i个数据元素ai的存储位置为:
数据结构考研笔记整理(全)

数据结构考研笔记整理(全)一、第二章线性表●考纲内容●一、线性表的基本概念●线性表是具有相同数据结构类型的n个数据元素的有限序列;线性表为逻辑结构,实现线性表的存储结构为顺序表或者链表●二、线性表的实现●1、顺序表●定义(静态分配)●#define MaxSize 50 \\ typedef struct{ \\ ElemType data[MaxSize];\\ intlength;\\ }SqList;●定义(动态分配)●#define MaxSize 50\\ typedef strcut{\\ EleType *data; //指示动态非配数组的指针\\ int MaxSize,length;\\ }SqList;●c的动态分配语句为L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize);●c++动态分配语句为L.data=new ElemType[InitSize];●插入操作●删除操作●按值寻找●2、链表●单链表●单链表的定义●●头插法建立单链表●●尾插法建立单链表●●按序号查找getElem(LinkList L,int i)和按值查找locateElem(LinkListL,ElemType e)●插入结点(后插)●p=getElem(L,i-1); //查找插入位置的前驱结点\\ s.next=p.next;\\p.next=s;●将前插操作转化为后插操作,即先将s插入的p的后面然后调换s和p的数据域●s.next=p.next;\\ p.next=s.next;\\ temp=p.data;\\ p.data=s.data;\\s.data=temp;●删除结点●p.getElem(L,i-1);\\ q=p.next;\\ p.next=q.next;\\ free(q);●双链表(结点中有prior指针和next指针)●循环链表●静态链表●借助数组来描述线性表的链式存储结构,结点中的指针域next为下一个元素的数组下标●三、线性表的应用●使用的时候如何选择链表还是顺序表?●表长难以估计,经常需要增加、删除操作——链表;表长可以估计,查询比较多——顺序表●链表的头插法,尾插法,逆置法,归并法,双指针法;顺序表结合排序算法和查找算法的应用●小知识点(选择题)二、第三章栈,队列和数组●考纲内容●一、栈和队列的基本概念●栈:后进先出,LIFO,逻辑结构上是一种操作受限的线性表●队列:先进先出,FIFO,逻辑结构上也是一种操作受限的线性表●二、栈和队列的顺序存储结构●栈的顺序存储●●队列的顺序存储●进队:队不满时,送值到队尾元素,再将队尾指针加一●出队:队不空时,取队头元素值,再将队头指针加一●判断队空:Q.front==Q.rear==0;●循环队列(牺牲一个单元来区分队空和队满,尾指针指向队尾元素的后一个位置,也就是即将要插入的位置)●初始:Q.front==Q.rear●队满:(Q.rear+1)%MaxSize=Q.front●出队,队首指针进1:Q.front=(Q.front+1)%MaxSize●入队,队尾指针进1:Q.rear=(Q.rear+1)%MaxSize●队列长度:(Q.rear+MaxSize-Q.front)%MaxSize●三、栈和队列的链式存储结构●栈的链式存储●●队列的链式存储●实际是上一个同时带有头指针和尾指针的单链表,尾指针指向单链表的最后一个结点,与顺序存储不同,通常带有头结点●四、多维数组的存储●行优先:00,01,02,10,11,12●列优先:00,10,01,11,02,12●五、特殊矩阵的压缩存储●对称矩阵●三角矩阵●三对角矩阵(带状矩阵)●稀疏矩阵●将非零元素及其相应的行和列构成一个三元组存储●十字链表法●六、栈、队列、数组的应用●栈在括号匹配中的应用●栈在递归中的应用●函数在递归调用过程中的特点:最后被调用的函数最先执行结束●队列在层次遍历中的应用●二叉树的层次遍历●1跟结点入队●2若队空,则结束遍历,否则重复3操作●3队列中的第一个结点出队并访问,若有左孩子,则左孩子入队;若有右孩子,则右孩子入队●重点为栈的(出入栈过程、出栈序列的合法性)和队列的操作及其特征●小知识点(选择题)●n个不同元素进栈,出栈元素不同排列的个数为{2n\choose n }/(n+1)●共享栈是指让两个顺序栈共享一个存储空间,将两个栈的栈底分别设置在共享空间的两端,两个栈顶向共享空间的中间延伸,可以更有效的利用存储空间,同时对存储效率没有什么影响●双端队列是指允许两端都可以进行入队和出队操作的队列●输出受限的双端队列:允许两端插入,只允许一端删除●输入受限的双端队列:允许两端删除,只允许一端插入三、第四章串●考纲内容●字符串模式匹配●暴力算法●注意指针回退时的操作是i=i-j+2;j=j+1;●kmp算法●手工求next数组时,next[j]=s的最长相等前后缀长度+1,其中s为1到j-1个字符组成的串●在实际kmp算法中,为了使公式更简洁、计算简单,如果串的位序是从1开始的,则next数组需要整体加一;如果串的位序是从0开始的,则next数组不需要加一●根据next数组求解nextval数组:如果p[j]==p[next[j]],则nextval[j]=nextval[next[j]],否则nextval[j]=next[j];●小知识点●串和线性表的区别:1线性表的数据元素可以不同,但串的数据元素一般是字符;2串的操作对象通常是子串而不是某一个字符四、第五章树与二叉树●考纲内容●一、树的基本概念●定义●树是一种递归的数据结构,是一种逻辑结构●树的性质●结点数为n,则边的数量为n-1●树中的结点数等于所有结点的度数之和加1(一个结点的孩子个数称为该结点的度,树中结点的最大度数称为树的度,每一条边表示一个结点,对应一个度,只有根结点上面无边,故结点树=度数之和+1)●度为m的树中第i层至多有m^{i-1}个结点(i\geq1)(m叉树的第i层最多有m^{i-1}个结点)●高度为h的m叉树至多有(m^h-1)/(m-1)个结点(假设每一个结点都有m个孩子,则由等比数列的求和公式可以推导出该式子)●具有n个结点的m叉树的最小高度是\lceil log_m(n(m-1)+1)\rceil(由高度为h的m叉树的最大结点树公式有,n满足式子(m^{h-1}-1)/(m-1) \leq n\leq (m^h-1)/(m-1))●高度为h的m叉树至少有h个结点;高为h,度为m的树至少有h+m-1个结点(m叉树并不等于度为m的树,m叉树可以为空树,要求所有结点的度小于等于m,而度为m的树一定有一个结点的度数为m)●二、二叉树●二叉树的定义及其主要特征●定义●特点●每个结点至多只有两颗子树●二叉树是有序树,其子树有左右之分,次序不能颠倒,否则将成为另一颗二叉树,即使树中结点只有一颗子树,也要区分他是左子树还是右子树●特殊的二叉树●满二叉树:高度为h,结点数为2^h-1,所有叶子结点都集中在二叉树的最下面一层,除叶子结点外的所有结点度数都为2,从根结点为1开始编号,对于编号为i的结点,其父结点为\lfloor i/2 \rfloor,左孩子(若有)编号为2i,右孩子(若有)编号为2i+1,所以编号为偶数的结点只可能是左孩子,编号为奇数的结点只可能是右孩子●完全二叉树:删除了满二叉树中编号更大的结点,高为h,结点数为n的完全二叉树的每个结点的编号都与高度为h的满二叉树中编号为1到n的结点相同。
《数据结构C语言版》----第02章
同理可证:顺序表删除一元素的时间效率为: 同理可证:顺序表删除一元素的时间效率为: T(n)=(n-1)/2 ≈O(n) O(n) (
插入效 E = ∑ is 率: i=0
n
1 n n pi ( n − i ) = ∑ (n − i) = 2 n + 1 i=0
n −1 删除效 1 n −1 n −1 Edl = ∑ qi (n − i ) = ∑ (n − i ) = 率: n i =0 2 i =0
2.2 线性表的顺序表示和实现
顺序存储结构的线性表称作顺序表 1.顺序表的存储结构 顺序表的存储结构
实现顺序存储结构的方法是使用数组。数组把线性表 实现顺序存储结构的方法是使用数组。 使用数组 的数据元素存储在一块连续地址空间的内存单元中, 连续地址空间的内存单元中 的数据元素存储在一块连续地址空间的内存单元中,这样 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 线性表中逻辑上相邻的数据元素在物理存储地址上也相邻。 数据元素间的逻辑上的前驱、 数据元素间的逻辑上的前驱、后继逻辑关系就表现在数据 元素的存储单元的物理前后位置上。 元素的存储单元的物理前后位置上。 顺序表的存储结构如图所示
2.线性表抽象数据类型 2.线性表抽象数据类型
数据集合:{ 的数据类型为DataType 数据集合 { a0, a1, … , an-1 }, ai的数据类型为 (1) ListInitiate(L) 初始化线性表 (2) ListLength(L) 求当前数据元素个数 操作集合: 操作集合 (3) ListInsert(L,i,x) 插入数据元素 (4) ListDelete(L,i,x) 删除数据元素 (5) ListGet(L,i,x) 取数据元素
printf("参数 不合法 \n"); 参数i不合法 参数 不合法! return 0;
线性表的基本操作
}
23
顺序表上的基本运算
查找 查找指定数据元素x在表中的位置序号,若 v[i]==x,则算法返回值为i+1,若不存在数 据元素x,则返回0
24
顺序存储结构的优缺点
静态操作容易实现 根据定位公式容易确定表中元素的存储位置 元素随机存取 动态操作实现效率较低 插入和删除结点困难
由于表中的结点连续存放,在动态操作时,为 了保持元素的连续性,所以必须将某些结点向 后或向前依次移动
基本特征
有且只有一个“第一元素”,有且只有一个“最后元素” 除第一元素之外,其它元素都有唯一的直接前趋
除最后元素之外,其它元素都有唯一的直接后继
2
元素的含义
数据元素在不同问题中的含 义各不相同 可以是一个数、一个符号, 一个记录,或其它更复杂的 信息 这里的学生成绩表是一个线 性表 数据元素是每一个学生的信 息,包括:学号、姓名、成 绩共三个数据项
12
顺序表上的基本运算
插入算法 在线性表的第i个数据元素前,插入一个新数 据元素,使线性表的长度从n变成n+1
(a1, …, ai-1, ai, …, an) (a1, …, ai-1, x, ai, …, an)
数组下标 数据元素 数组下标 数据元素 序号 序号
0 1 2 3 在第6个元素 4 在第6个元素 之前插入26 5 之前插入26 6 7 8
在C语言中可借助数组实现 若每个元素占m个存储单元 第 i+1 个和第 i 个元素的存储位 置满足如下关系: LOC(ai+1)=LOC(ai)+m 第i个和第一个元素的存储位置 满足如下关系 LOC(ai)=LOC(a1)+(i-1)*m LOC(a1)是线性表的起始地址 取a1和ai的时间是相同的 是一种随机存取的存储结构
线性表ppt
假设在主函数中已经建立了线性表结构体s,并且要在第3 个位置插入88,语句如下:
insert ( &s,3,88);
其他特 VIP专享精彩活动
权
VIP专属身份标识
开通VIP后可以享受不定期的VIP随时随地彰显尊贵身份。
专属客服
VIP专属客服,第一时间解决你的问题。专属客服Q全部权益:1.海量精选书免费读2.热门好书抢先看3.独家精品资源4.VIP专属身份标识5.全站去广告6.名
以用来说明结构体变量:
Sqlist1 a; 在正式使用a之前必须为数据成员elem分配足够的空间。 语句如下:
a.elem=(Sqlist1 *)malloc(MAXSIZE*sizeof(Sqlist1)); 对结构体内elem子域的访问与前文有所不同。在输入/输出时 的情况,也与前文有所不同。在程序运行结束之前,这些动态 分配的存储空间还要释放归还给系统,语句如下:
(5) Insert(L,i,x) 在线性表中第i个元素之后(或之前)插入一个新元素x;
(6) Delete(L,i) 删除线性表中的第i个元素;
(7) Empty(L)
判断线性表是否为空;
(8) Clear(L)
将已知的线性表清理为空表;
第2章 线 性 表
在上述的操作运算中,最基本最重要的是插入、删除。 线性表的其他复杂操作和运算还有:对有序表的插入和删除; 按某种要求重排线性表中各元素的顺序;按某个特定值查找 线性表中的元素;两个线性表的合并等。
《第二章线性表》PPT课件
例 2-3
归并两个"其数据元素按值非递减有序 排列"的有序表 LA 和 LB,求得有序表 LC 也具有同样特性.
设 La = <a1, …, ai, …, an>, Lb = <b1, …, bj, …,
ListInsert<Lc, ++k, ai>; ++i; } else { // 将 bj 插入到 Lc 中
ListInsert<Lc, ++k, bj>; ++j; }
void MergeList<List La, List Lb, List &Lc> { // 本算法将非递减的有序表 La 和 Lb 归并为 LcInitList<Lc>; // 构造空的线性表 Lc
是最后一个元素,则用next_e 返回它的后继,否则操作失 败,next_e无定义。
GetElem< L, i, &e >
〔求线性表中某个数据元素〕
初始条件:线性表 L 已存在,
且 1≤i≤LengthList(L)
操作结果:用 e 返回L中第 i 个元素的值。
LocateElem< L, e, compare< > >
bj 插入到 LC 中; 4.重复 2 和 3 两步,直至 LA 或 LB 中元素
被取完为止; 5.将 LA 表或 LB 表中剩余元素复制插入到
LC 表中.
// La 和 Lb 均非空,i = j = 1, k = 0 GetElem<La, i, ai>; GetElem<Lb, j, bj>; if <ai <= bj> { // 将 ai 插入到 Lc 中
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Company LOGO 第2章线性表《数据结构(C#语言描述)》配套PPT 北京大学出版社制作:陈广博客:2.1 线性表的定义•线性表(Linear List)是具有相同特性的数据元素的一个有限序列…a1a2a n-1a n•线性表的顺序存储结构是指用一块地址连续的存储空间依次存储线性表的数据元素。
2.2.1顺序表的特点容量固定1105106107108109110201202203204205206207208209210301302303304305306307308309310101102103104A 班宿舍B 班宿舍安排A 班40人住入宿舍安排B 班50人住入宿舍2.2.1顺序表的特点访问速度快2•由于线性表中每个元素所占用的空间是相同的,只需按照公式计算便可以快速地访问指定元素。
假设顺序表中第一个元素的位置是Loc ,每个数据元素所占用的存储空间为n :a 1a 2...a i ...线性存储空间下标位置01i-1存储地址Loc Loc +n Loc +(i –1)*n2.2.2数组(Array)•线性表的顺序存储结构在C#中的最直接表现形式就是数组。
它存在于System命名空间之中,是一种内置数据类型,数组是最基础也是存取速度最快的一种集合类型。
2.2.2数组(Array )•当数组元素为值类型时StackHeap代码int[] arrInt arrInt =new int[5];0000001234arrInt[2] = 5;arrInt[4] = 3;532.2.2数组(Array )•当数组元素为引用类型时StackHeap代码Control[] arrCtrl arrCtrl=new Control[5];null null null null null01234arrInt[0] = new Button();arrInt[3] = new Label();ButtonLabel2.2.3System.Collections.ArrayList 容量固定2105106107108109110201202203204206207208209210301302303304305306307308309310101102103104A 班宿舍B 班宿舍先将A 班所有学生搬入连续的205先将A 班补录的10个学生安排到205内如果一个班级宿舍必须是连续的,A 班补录10人,该如何安这三间宿舍作为A 班的备用宿舍留空2.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs】代码讲解添加操作:_items 0123索引号Add(50)_size2.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs】代码讲解添加操作:_items 0123索引号Add(200)50_size2.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs】代码讲解添加操作:_items 0123索引号Add(6)50_size2002.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs 】代码讲解插入操作:Insert(0,12)_size_items 0123索引号45675020062.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs 】代码讲解插入操作:Insert(2,73)_size_items 0123索引号4567502006122.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs 】代码讲解删除操作:RemoveAt(0)_size_items 0123索引号456712502006732.2.3System.Collections.ArrayList•【例2-1 ArrayList.cs 】代码讲解删除操作:RemoveAt(2)_size_items 0123索引号456750200673运行虚拟线性表演示程序2.2.4类型安全•数组和ArrayList的本质区别在于前者是类型安全的,而后者不是类型安全的。
ArrayList为了兼容所有类型的对象,使用了object数组,这给使用带来了一些的麻烦。
•.NET 2.0版本的泛型的出现完美地解决了集合类的安全问题,新版本使用System.Collections.Generic命名空间下的List<T>类取代了原来的ArrayList类。
•在实际编程中,应使用List<T>代替ArrayList•线性表的另一种常见存在形式——链式存储结构,又称链表(Linked List)。
顺序表必须占用一整块事先分配的存储空间,而链表则不需要。
链表在逻辑上相邻的元素在物理位置上可以不相邻。
•在链式存储中,每个存储点不仅包含所存元素本身的信息,而且包含元素之间逻辑关系的信息。
•链表又分为单链表和双链表•单向链表的元素间的表面物理关系如同一盘散沙。
如果每个元素只包含元素的有用的数据内容,则这些元素之间将毫无任何内在逻辑关系。
单向链表的终端结点的指针域为空,表示链表的结束。
2.3.1单向链表链表的结点单向链表a数据域指针域开始结点终端结点head a1a2a n头指针…a32.3.1单向链表•【例2-3 LInkedList.cs】代码讲解•添加操作:headAdd(6) 0索引号2.3.1单向链表•【例2-3 LInkedList.cs】代码讲解•添加操作:head6Add(12) 0索引号12.3.1单向链表•【例2-3 LInkedList.cs】代码讲解•添加操作:head6Add(7) 1201索引号22.3.1单向链表•【例2-3 LInkedList.cs】代码讲解•插入操作:head6Insert(1,32) 127012索引号132.3.1单向链表•【例2-3 LInkedList.cs】代码讲解•插入操作:head6Insert(0,19)12732索引号0231024132.3.1单向链表•【例2-3 LInkedList.cs 】代码讲解•删除操作:head 9RemoveAt(2)2123索引号823416运行虚拟线性表演示程序01232.3.2循环链表•循环链表是另一种形式的链式存储结构。
•循环链表的最后一个结点的指针指向第一个结点,从而使整个链表成为一个环,这种形式的链表就叫做单向循环链表。
2.3.2循环链表head a 1a 2a n…a 3taila 1a 2a n…a 3头指针形式的单向循环链表尾指针形式的单向循环链表2.3.1循环链表约瑟夫问题1加斯帕·蒙日(1746~1818年)是法国数学家,画法几何的创始人。
他在《数学的游戏问题》中讲了一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人(用数字M表示)就将他扔入大海,如此循环进行直到仅余15个人为止。
问怎样排法,才能使每次投入大海的都是非教徒。
2.3.1循环链表为解决约瑟夫问题而设计的单向循环链表2应实现如下功能•添加元素•拥有指示当前选中元素的游标•游标可循环访问链表中各元素•可将游标向前移动指定步数•可删除当前游标所指定的元素2.3.2循环链表•【例2-4 CircularLInkedList.cs】代码讲解•添加操作:tail Add(1)currentPrev2.3.2循环链表•【例2-4 CircularLInkedList.cs】代码讲解•添加操作:Add(2) currentPrev1tail12.3.2循环链表•【例2-4 CircularLInkedList.cs 】代码讲解•添加操作:tailAdd(3)2currentPrev12.3.2循环链表•【例2-4 CircularLInkedList.cs 】代码讲解•元素的删除:tailRemoveCurrentMode()2currentPrev345为当前选中元素12.3.2循环链表•【例2-4 CircularLInkedList.cs 】代码讲解•游标的移动:tail Move(2)2currentPrev345为当前选中元素12.3.2循环链表•【例2-4 CircularLInkedList.cs 】代码讲解•游标的移动:tail Move(3)2currentPrev4为当前选中元素532.3.2循环链表•带密码的约瑟夫问题:编号为1,2,......,n 的n 个人按照顺时针方向围坐一圈,每个人有且只有一个密码(正整数)。
一开始任选一个正整数作为报数上限值,从第一个人开始顺时针方向自1开始报数,报到m 时停止报数。
报m 的人出列,将他的密码作为新的m 值,从他在顺时针方向的下一个人开始重新报数,如此下去,直到所有人全部出队为止。
设计一个程序来求出出队顺序。
请思考如何修改单向循环链表以求解这个问题。
思考32.3.3双向链表•单链表的各结点只有指向其后继结点的指针域next,只能顺着一个方向寻找。
如果希望很方便地查找前驱,可以给每个结点再加一个指向前驱的指针域,使链表可以进行双方向查找。
用这种结点结构组成的链表称为双向链表,简称双链表。
2.3.3双向链表双向链表结构图双向链表的结点nextdata prev …双向链表开始结点终端结点head头指针a 1a 2a 3a n2.3.3双向链表双向链表中结点的插入1在n之前插入sp n代码s.next = n;n.prev.next = s; s.prev = n.prev; n.prev = s;s 请注意代码执行顺序2.3.3双向链表双向链表中结点的插入1在p之后插入s代码p n s.prev = p;s.next = p.next;p.next.prev = s;sp.next = s;2.3.3双向链表双向链表中结点的删除1删除结点ssp n2.3.3双向链表•C#中实现了双向链表的数据结果是泛型集合System.Collections.Generic.LinkedList<T>。
它是一个通用链表类,不支持随机访问(使用索引访问)。
它实现了很多添加元素的方法:•AddAfter 在现有节点后添加新的节点或值•AddBefore 在现有节点前添加新的节点或值•AddFirst 在开头处添加新的节点或值•AddLast 在结尾处添加新的节点或值线性表顺序表链表数组(Array)动态数组(ArrayList、List<T>、BitArray)单向链表(ListDictionary)双向链表(LinkedList<T>)循环链表单向循环链表双向循环链表线性表的分类顺序表性能小结1优点:•算法实现简单,不会为描述元素间的逻辑关系而增加额外的内存空间。