算法与数据结构 张乃孝 前三章习题课
Chap3算法与数据结构—C语言描述(第2版)张乃孝编课件

E = ""
(注意区分空串""与空格串" "区别)
T = “ABBABBCA ” t= “ABB ABBCA ” (T和t不等) P= “BBC ” (P是T的子串,在T的位置是5)
子串:串中任意个连续的字符组成的子序列。 主串:包含子串的串相应地称为主串。 特别地,空串是任意串的子串。任意串s都是s本身的子 串。 除s本身之外,s的其它子串称为s的真子串。 位置:字符在序列中的序号。子串在主串中的位置则以 子串的第一个字符在主串中的位置来表示。 相等:两个串的长度相等,并且对应位置的字符都相等。
2 链接表示
在串的链接表示中,每个结点包含两个字段:字符和指 针,分别用于存放字符和指向下一个结点的指针。这样一个 串就可 用一个单链表来表示,其类型定义为:
struct StrNode; typedef struct StrNode *PStrNode; struct StrNode { char c; PStrNode link; }; typedef struct StrNode *LinkString; /* 链串的结点 */ /* 结点指针类型 */ /* 链串的结点结构 */
String concat (String s1, Sting s2 ) //返回将串s1和s2拼接在一起构成的一个新串。 String subStr (String s, int i, int j ) //在串s中,求从串的第i个字符开始连续j个字符所构成的子串。 int index (String s1, String s2 ) //如果串s2是s1的子串,则可求串s2在串s1中第一次出现的位置。 end ADT String
}
第1讲 数据结构 绪论

主Hale Waihona Puke 教师石连栓 软件教研室信息技术工程学院
课程安排
讲课学时: 讲课学时:36 参考书目: 参考书目
《算法与数据结构》 张乃孝主编. 高等教育出版社 算法与数据结构》 张乃孝主编 《数据结构》 数据结构》 严蔚敏等. 严蔚敏等 清华大学出版社
《计算机算法设计与分析》(第3版) 王晓东编著 电子工业出版社 计算机算法设计与分析》 第 版 《算法设计》 Jon KleinBerg Eva Tardos 著 张立昂 屈婉玲 译 清华大学出版社 算法设计》
逻辑结构划分方法二 一、集合 结构中的数据元素除了同属于一种 类型外,别无其它关系。 类型外,别无其它关系。 二、线性结构 结构中的数据元素之间存在一 对一的关系。 对一的关系。 三、树型结构 结构中的数据元素之间存在一 对多的关系。 对多的关系。 四、图状结构或网状结构 结构中的数据元素 之间存在多对多的关系。 之间存在多对多的关系。
18
存储结构 数据元素及其关系在计算机存储器中的存 储方式。 储方式。 是逻辑结构用计算机语言的实现, 是逻辑结构用计算机语言的实现,它依赖 于计算机语言。 于计算机语言。 存储结构两方面的内容 (1)数据元素自身值的表示(数据域) )数据元素自身值的表示(数据域) (2)该结点与其它结点关系的域(链域) )该结点与其它结点关系的域(链域)
首先,算法必须是“正确” 首先,算法必须是“正确”的 (1)执行算法所耗费的时间(效率要高 时间复杂度) 执行算法所耗费的时间( 时间复杂度) 执行算法所耗费的时间 效率要高,时间复杂度 (2)执行算法所耗费的存储空间( 主要考虑辅存空间 ; 执行算法所耗费的存储空间( 主要考虑辅存空间; 执行算法所耗费的存储空间 低存储要求,空间复杂度 空间复杂度) 低存储要求 空间复杂度) (3)算法的可读性、 易维护性要好 ( 易于理解 , 易于编 算法的可读性、易维护性要好(易于理解, 算法的可读性 易于调试) 码,易于调试) (4)健壮性, 即当输入一些非法数据时 , 算法也应做出 健壮性,即当输入一些非法数据时, 健壮性 适当的反应或进行处理。 适当的反应或进行处理。
张乃孝主编《算法与数据结构—C语言描述》.

(a)RL(0)型调整
(b)RL(L)型调整
(c)LR(R)型调整
16
201
16
17
202
图6.24
(a)删除3后的B树
(a)删除前的B树
18
208
9
q1=q2=q3=q4=q5=q6=1
q0= q1=q2=q3=q4=q5=q6=11
19
214
14
20
223
-7
21
223
-5
9
115
12
i<=t->n;
i<t->n;
10
118
-10
*PCSNode;
*CSTree;
11
130
5
每个内部结点
每个分支结点
12
130
-5
前序周游
先根周游
13
131
15
t==NULL
p==NULL
14
164
-4
小于基本区域
不大于基本区域
15
193
图6.21
(a)LR(0)型调整
(b)LR(L)型调整
张乃孝主编《算法与数据结构—C语言描述》
勘误表
二○○三年一月
序号
页码
行号
原文
更正
1
3
-7
2
44
7
*pclink
*pclist
3
76
3~6
/*见下栏左侧*/
4
76
5
107
8
(i=1,2,3...)
/*删除*/
6
107
10
Chap7_算法与数据结构—C语言描述(第2版)张乃孝编课件

插入算法
int insert (PBinSearchTree ptree, KeyType key)
例 {10, 18, 3, 8, 12, 2, 7, 4} 10 10 18 10 10 18 10 18
3
3 8
3
18
8 12 10
10
3 2 18 8 12 2 3
10
18 8 12 2 3
10 3 2 7 4 8 18 12
二叉排序树的插入
插入原则:若二叉排序树为空,则插入结点应为 新的根结点;否则,继续在其左、右子树上查找, 直至某个叶子结点的左子树或右子树为空为止, 则插入结点应为该叶子结点的左孩子或右孩子 二叉排序树生成:从空树出发,经过一系列的查 找、插入操作之后,可生成一棵二叉排序树
第7章 高级字典结构
7.3二叉排序树
定义
定义:二叉排序树或是一棵空树,或是具有下列性质的 二叉树:
若它的左子树不空,则左子树上所有结点的值均小 于它的根结点的值
若它的右子树不空,则右子树上所有结点的值均大 10 于或等于它的根结点的值 它的左、右子树也分别为二叉排序树 3 18
2 7 4
18 8 12
7
4
7Hale Waihona Puke 中序遍历二叉排序树可得到一个关键字的有序序列
二叉排序树的删除
为了删除一个二叉树中的结点,必须首先找到这个结点,然 后选择下面给出两种方法删除之,以保证删除后仍满足二 叉排序树的定义。 第一种方法∶ (1) 如果被删除结点p没有左子树,则用p的右子女代替p。 (2) 否则,在p的左子树中,找出关键码最大的一个结点r ( r 处于p的左子树中最右下角的位置,r 一定无右子女), 将r 的右指针指向p的右子女,用p的左子女代替p结点。 第二种方法∶ (1) 同第一种方法的(1)。 (2) 同第一种方法找到r结点,用r结点代替被删除的结点 p,p原来的左右子女不变。并且用原来r的左子女代替原来 的r结点。
Chap4算法与数据结构—C语言描述(第2版)张乃孝编课件

4.1 栈及其抽象数据类型
4.1.1. 定义
栈是限定在表尾进行插入或删除操作的线性表。表尾端称 栈顶,表头端称栈底。如图。 出栈 进栈 栈的修改是按后进先出 的原则进行的。 a 栈顶
n
... a2 a1
栈底
例1.一个栈的进栈序列是a,b,c,d,e,则栈不 可能的出栈序列是:
(A)edcba (B)decba (C) dceab (D)abcde
从pastack所指的栈中删除(或称弹出)一个元素。 当栈不空时,通过将栈顶变量减1达到元素删除的目的。 5. 取栈顶元素运算 程序实现
DataType top_seq( PSeqStack pastack )
当pastack所指的栈不为空栈时,将栈顶元素取出,而栈 本身未发生任何变化。
4.2.2链接表示
4.2 栈的实现
4.2.1顺序表示
typedef int DataType; /* 定义栈元素的数据类型, 这里定义为整型 */ struct SeqStack /* 顺序栈类型定义 */ { int MAXNUM; /* 栈中能达到的最大元素个数 */ int t; /*栈顶元素位置*/ DataType *s; }; typedef struct SeqStack * PSeqStack; D PSeqStack pastack;
typedef int DataType ; /* 定义栈中元素类型为整型, 也可定义为其他类型 */ struct Node; typedef struct Node * Pnode; struct Node /* 单链表结点结构 */ { DataType info; PNode link; }; struct LinkStack /* 链接栈类型定义 */ { PNode top; /* 指向栈顶结点 */ }; typedef struct LinkStack *PLinkStack ;
数据结构习题课

本课程用Python语言作为教学及上机使用的语言。
英文简介
This course is about teaching algorithms and data structures by using Python.
数据结构习题课课程详细信息
课程号
00137190
学分
0
英文名称
Data Structures
先修课程
计算概论
中文简介
基本目的:使学生较全面地理解算法和数据结构的概念、掌握各种数据结构与算法的实现方式,比较不同数据结构和算法的特点。使学生不仅学到数据结构与算法的基本知识,还能提高用计算机解决实际问题的能力。
3.串:串的概念和基本操作,模式匹配,应用(约2课时)
4.栈与队列:栈的概念和应用,队列的概念、实现和应用(约4课时)
5.树与二叉树:树和二叉树的概念,树形数据组织的性质,基本树算法,应用(约6课时)
6.图:基本概念及术语,图的表示,图遍历,最短路径、最小生成树、拓扑排序、关键路径(约8课时)
7.字典与检索:字典与检索,字典的存储结构(约遇到的各种问题,进一步提高学生的Python编程能力。
1.算法和数据结构概论:算法的概念,算法分析,算法复杂性的基本概念和意义,数据结构概念,数据结构讨论的基本问题(约2课时)
2.线性表:线性数据结构,顺序存储实现(顺序表),链接实现(链接表),应用(约2课时)
8.排序:排序的基本概念,典型的排序算法,排序算法的复杂性分析(约6课时)
10.算法设计与分析初步(约2课时)
Chap3_算法与数据结构—C语言描述(第2版)张乃孝编课件

3.2 字符串的实现
顺序表示 链接表示
1 顺序表示
字符串的顺序表示,就是把串中的字符,顺序地存储在一 组地址连续的存储单元中。其类型定义为: struct SeqString { /* 顺序串的类型 */ int MAXNUM; /* 串允许的最大字符个数 */ int n; /* 串的长度,nMAXNUM */ char *c; }; typedef struct SeqString *PSeqString;
算法3.3 创建空链串
LinkString createNullStr_link( ) { LinkString pst; pst=(LinkString)malloc(sizeof(struct StrNode )); if( pst != NULL ) pst->link =NULL; return (pst); }
else
return(s1); if (p==NULL) return(s1); t = (PStrNode)malloc(sizeof(struct StrNode)); s1->head = t; for (k=1;k<=j;k++) /*连续取j个字符*/ { t->c = p->c; if (p->link!=NULL && k<j) { q=(PStrNode)malloc(sizeof(struct StrNode)); p = p->link; t->link = q; t = q; } else break; } t->link = NULL; return(s1);
2 抽象数据类型
ADT String is operations String createNullStr (void) int IsNullStr ( String s )
数据结构(徐孝凯编著)部分习题参考解答

数据结构(徐孝凯编著)部分习题参考解答第一章 绪论1.1 单选题1. A2. D3. B4. C5. D6. B7. D1.2 填空题(给单号题解答)1. 集合结构,线性结构,树结构,图结构 (次序无先后) 3. 1:1, 1:N, M:N (或者1对1,1对N ,M 对N) 5. 引用 7. 实参,值9. sizeof(a), a+i (或者&a[i],或者(char*)a+i*sizeof(a[i]))11. n, n(n+1)/2, O(n 2)13. O(n 3) 15. 35/12提示:在含有n 个元素的数表中顺序查找任一元素的平均比较次数为p c i i i n=∑1,p i为查找第i 个元素的概率,c i 是查找第i 个元素时需要比较的元素数,查找所有元素的概率之和为1,若查找每个元素的概率相同,则平均查找长度的计算公式可简化为11ni i nc =∑。
计算此题的计算式为)76543(121241131+++++⨯+⨯1.4 算法分析题(给单号题解答)1. 判断n 是否是一个素数,若是则返回数值1,否则返回0。
该算法的时间复杂度为O (n )。
3. 计算∑=ni i 1!的值。
时间复杂度为O (n 2)。
5. 打印出一个具有n 行的乘法表,第i 行(1≤i ≤n )中有n-i+1个乘法项,每个乘法项为i 与j (i ≤j ≤n )的乘积。
时间复杂度为O (n 2)。
7. 矩阵相乘,即a[M][N]×b[N][L]→c[M][L]。
时间复杂度为O (M ×N ×L)。
1.5 算法设计题 1. (给单号题解答)(1) void InitQuadratic(Quadratic& q, float aa, float bb, float cc) { q.a=aa; q.b=bb; q.c=cc; }(3) float Eval(Quadratic& q, float x) { return (q.a*x*x+q.b*x+q.c);}(5) void Print(Quadratic& q){if (q.a) cout<<q.a<<"x**2";if(q.b)if(q.b>0)cout<<"+"<<q.b<<"x";elsecout<<q.b<<"x";if(q.c)if(q.c>0)cout<<"+"<<q.c;elsecout<<q.c;cout<<endl;}2.(给单号题解答)(1) char Compare(SimpleType x1, SimpleType x2){if(x1>x2) return '>';else if(x1==x2) return '=';else return '<';}时间复杂度为O(1)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
r–>next=p; r=p; } if (r!=NULL) r–>next=NULL; return(head); }
linklist createlistr1( ){ char ch; linklist head=(linklist)malloc(sizeof(listnode)); listnode *p,*r r=head; while((ch=getchar( ))!=‵\n′{ p=(listnode*)malloc(sizeof(listnode)); p–>data=ch; r–>next=p; r=p; } r–>next=NULL; return(head); }
的指针。若链表中附设头结点,则不管线性表是否为空表, 头指针均不为空,否则表示空表的头指针为空。
2.1 单项选择题 1. 一个向量(即一批地址连续的存储单元)第一个元素的存储 地址是100,每个元素的长度为2,则第5个元素的地址是__ __。 B A. 110 B. 108 C. 100 D. 120 A 2. 线性表的顺序存储结构是一种__ _的存储结构,而链式存储 C 结构是一种__ _的存储结构。 A.随机存取 B.索引存取 C.顺序存取 D.散列存取 B 3. 线性表的逻辑顺序与存储顺序总是一致的,这种说法__ _。 A. 正确 B. 不正确 4. 线性表若采用链式存储结构时,要求内存中可用存储单元的 D 地址__ _。 A. 必须是连续的 B. 部分地址必须是连续的 C. 一定是不连续的 D. 连续或不连续都可以
L 指向无头结点的线性链表,写出删除链表中从下标为I的结 点开始的连续k个结点的算法
Linklist Del (linklist L,int I,int k) {pnode p,q; int j=0; p=L; while(p->link!=NULL&&j<i) {p=p->link;j++} for(j=1;j<=k;j++) {q=p->link; p->link=q->link; free(q); } Return(L);}
删除单链表中值相同的多余结点
Diff_link(Linklist llist) {pnode p,q,r; p=llist->link; while( p!=NULL) {q=p; r=q->link; while(r!=NULL) {if(r->info==p->info) {t=r->link; q->link=t; free(r); r=t; }
如果我们在链表的开始结点之前附加一个结点, 并称它为头结点,那么会带来以下两个优点: a、由于开始结点的位置被存放在头结点的 指针域中,所以在链表的第一个位置上的操作就 和在表的其它位置上的操作一致,无需进行特殊 处理;
b、无论链表是否为空,其头指针是指向头结点
在的非空指针(空表中头结点的指针域为空),
5. 在以下的叙述中,正确的是__C_。 线性表的顺序存储结构优于链表存储结构 线性表的顺序存储结构适用于频繁插入/删除数据元素的情况 线性表的链表存储结构适用于频繁插入/删除数据元素的情况 线性表的链表存储结构优于顺序存储结构 6. 每种数据结构都具备三个基本运算:插入、删除和查找,这 A 种说法__ _。 A. 正确 B. 不正确 A 7. 不带头结点的单链表head为空的判定条件是____。 A. head= =NULL B. head->next= =NULL C. head->next= =head D. head!=NULL B 8. 带头结点的单链表head为空的判定条件是____。 A. head= =NULL B. head->next= =NULL C. head->next= =head D. head!=NULL
首元结点、头结点、头指针的区别
首元结点:链表中存储线形表中第一个数据元素的结点
头结点:在链表首元结点之前附设一个结点。该结点的数 据域不存储数据元素,其作用是为了对链表进行操作时,
可以对空表、非空表的情况以及对首元结点进行统一处理。点)
的指针。若链表中附设头结点,则不管线性表是否为空表, 头指针均不为空,否则表示空表的头指针为空。
说明:第一个生成的结点是开始结点,将开始
结点插入到空表中,是在当前链表的第一个位
置上插入,该位置上的插入操作和链表中其它
位置上的插入操作处理是不一样的,原因是开
始结点的位置是存放在头指针(指针变量)中,
而其余结点的位置是在其前趋结点的指针域中。 算法中的第一个if语句就是用来对第一个位置 上的插入操作做特殊处理。
linklist creater( ) { char ch; linklist head; listnode *p,*r; //(, *head;) head=NULL;r=NULL; while((ch=getchar( )!=‵\n′){ p=(listnode *)malloc(sizeof(listnode)); p–>data=ch; if(head==NULL) { head=p; r=head;} else
已知线性表A的长度为n,并且采用顺序存储结构,写一 算法删除线性表中所有值为X的元素
Del (sqlist L,datatype x) {int I,j; for(I=0;i<L->n;I++) if(L->data[i]==x) {for(j=I;j<L->n;j++) L->data[j]=L->data[j+1]; L->n--; } }
(2)设L是不带头结点的单链表。 算法如下: int Length_LinkList2 (LinkList L) { Lnode * p=L; int j; if (p==NULL) return 0; /*空表的情况*/ j=1; /*在非空表的情况下,p所指的是第一个结点 */; while (p->next ) { p=p->next; j++ } return j; }
首元结点、头结点、头指针的区别
习题选讲 栈与队列
树与二叉树
首元结点、头结点、头指针的区别
首元结点:链表中存储线形表中第一个数据元素的结点
头结点:在链表首元结点之前附设一个结点。该结点的数 据域不存储数据元素,其作用是为了对链表进行操作时,
可以对空表、非空表的情况以及对首元结点进行统一处理。
头指针:是指向链表中第一个结点(头结点或首元结点)
else {q=r;r=r->link;} } P=p->link }}
b、无论链表是否为空,其头指针是指向头结点
在的非空指针(空表中头结点的指针域为空),
因此空表和非空表的处理也就统一了。
求表长 算法思路:设一个移动指针p和计数器j,初始化后 ,p所指结点后面若还有结点,p向后移动,计数器 加1。 (1)设L是带头结点的单链表(线性表的长度不包括头结 点)。 算法如下: 加头没加尾 int Length_LinkList1 (LinkList L) { Lnode * p=L; /* p指向头结点*/ int j=0; while (p->next) { p=p->next; j++ } /* p所指的是第 j 个结点*/ return j; }
12. 在一个单链表中,若p所指结点不是最后结点,在p之后插 B 入s所指结点,则执行____。 A. s->next=p; p->next=s; C. s->next=p->next; p=s; B. s->next=p->next; p->next=s; C. p->next=s; s->next=p;
该算法只是对链表中顺序扫描一边即完成了倒置,所以 时间性能为O(n)。
2.22 void LinkList_reverse(Linklist &L)//链表的就地逆 置;为简化算法,假设表长大于2
Rev(linklist L) //带头结点的单链表 {Pnode p,q,r; p=L->link;if(p==NULL) return; q=p->link; if(q==NULL) return; r=q->link; while(r!=NULL) {q->link=p; p=q; q=r; r=r->link;} q->link=p; L->link->link=NULL; L->link=q; }
C 9. 非空的循环单链表head的尾结点(由p所指向)满足____。 A. p->next= =NULL B. p= =NULL C. p->next= =head D. p= =head 10. 在双向循环链表的p所指结点之后插入s所指结点的操作是 D ____。 A. p->right=s; s->left=p; p->right->left=s; s->right=p->right; B. p->right=s; p->right->left=s; s->left=p; s->right=p->right; C. s->left=p; s->right=p->right; p->right=s; p->right->left=s; D. s->left=p; s->right=p->right; p->right->left=s; p->right=s; 11. 在一个单链表中,已知q所指结点是p所指结点的前驱结点, C 若在q和p之间插入s结点,则执行____。 A. s->next=p->next; p->next=s; B. p->next=s->next; s>next=p; C. q->next=s; s->next=p; D. p->next=s; s->next=q;