数据结构课程教学汇报-李春葆

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

算法设计思路:
p a1 A 尾插法 B 头插法 p b1 ...... bn ∧
例、假定采用带头节点的单链表保存单词,当两个单词 有相同的后缀时,则可共享相同的后缀存储空间,例如, “loading”和“being”,如下图所示。
str1
l
str2
o
a
d
p
i b e
n
g ∧
设str1和str2分别指向两个单词所在单链表的头节点, 链表节点结构为:
void PathAll(ALGraph *G,int u,int v,int path[],int d) //d是到当前为止已走过的路径长度,调用时初值为-1 { int w,i; ArcNode *p; visited[u]=1; d++; //路径长度增1 path[d]=u; //将当前顶点添加到路径中 if (u==v && d>1) //输出一条路径 { printf(" "); for (i=0;i<=d;i++) printf("%d ",path[i]); printf("\n"); } p=G->adjlist[u].firstarc; //p指向u的第一个邻接点 while (p!=NULL) { w=p->adjvex; //w为u的邻接顶点 if (visited[w]==0) //若顶点未标记访问,则递归访问之 PathAll(G,w,v,path,d); p=p->nextarc //找u的下一个邻接顶点 } visited[u]=0; //恢复环境 }
承上 启下
计算机导论 C语言 离散数学
算法设计与分析 操作系统 编译原理 数据库原理 软件工程
数据结构

数据结构课程的要求
掌握基本编 程方法 掌握数据组 织和数据处 理的方法 掌握大型软 件开发方法
基本 要求
课程 关系
C语言
学习识字
数据结构
学习写作文
软件工程
学习写小说 与语文 学习过 程类比
动手能力(上机实验)
例、 假设二叉树采用二叉链存储结构存储,试设计一个算 法,计算一棵给定二叉树的所有单分支节点个数。 解:计算一棵二叉树b中所有单分支节点个数的递归模型f(b) 如下: f(b)=0 若b=NULL f(b)=f(b->lchild)+f(b->rchild)+1
f(b)=f(b->lchild)+f(b->rchild)
其他情况
int count(Node *L) { if (L==NULL) return 0; else return count(L->next)+1; }
(2)正向显示以L为首节点指针的单链表的所有节点值 递归模型如下: f(L)不做任何事件 当L=NULL
f(L)输出L->data;f(L->next)
例、假设图G采用邻接表存储,设计一个算法,输出图G 中从顶点u到v的所有简单路径。 解:所谓简单路径是指路径上的顶点不重复。利用回溯的 深度优先搜索方法。 从顶点u开始进行深度优先搜索,在搜索过程中,需要把 当前的搜索线路记录下来。为此设立一个数组path保存走过的 路径,用d记录走过的路径长度。若当前扫描到的顶点u等于v 时,表示找到了一条路径,则输出路径path。
1、单链表算法设计
基于建表的算法:这类算法直接或间接地转换成建
表过程,如果新建表的次序与原来的次序相同,则
采用尾插法;如果新建表的次序与原来的次序相反, 则采用头插法。 基于查找、插入或删除的算法:这类算法以单链表 的基本运算为基础,包含有节点的查找、插入或删
除操作。
例、设C={a1,b1,a2,b2,…,an,bn}为一线性表,采用带头 节点的hc单链表存放,设计一个就地算法,将其拆分为 两个线性表(它们都用单链表存放),使得: A={a1,a2,…,an},B={b1,b2,…,bn} C a1 A a1 B b1 b2 ...... bn ∧ a2 ...... an ∧ b1 ...... bn ∧
data next
请设计一个时间上尽可能高效的算法,找出由str1和 str2所指向两个链表共同后缀的起始位置(如图中字符i所 在节点的位置p)。要求: (1)给出算法的基本设计思想。 (2)根据设计思想,采用C或C++或JAVA语言描述算 法,关键为之处给出注释。 (3)说明你所设计算法的时间复杂度。 本题为2012年全国考研题。
int visited[MAXV]={0}; //全局变量 void isPath(ALGraph *G,int u,int v,bool &flag) //flag表示uv是否有路径,初始时flag=false { int w; ArcNode *p; visited[u]=1; p=G->adjlist[u].firstarc; //p指向u的第一条边 while (p!=NULL) { w=p->adjvex; //w为u的邻接顶点 if (w==v) { flag=true; return; } else if (visited[w]==0) //若顶点未标记访问,则递归访问之 isPath(G,w,v); //从顶点w出发继续查找 p=p->nextarc //找u的下一个邻接顶点 } }
2、递归算法设计
求递归模型的步骤:
(1)对原问题 f(s)进行分析,称为“大问题”,假设 出合理的“小问题”f(s‘)(与数学归纳法中假设n=k-1时 等式成立相似); (2)假设f(s‘)是可解的,在此基础上确定f(s)的解, 即给出f(s)与f(s’)之间的关系(与数学归纳法中求证 n=k 时等式成立的过程相似); (3)确定一个特定情况(如f(1)或f(0))的解,由此作 为递归出口(与数学归纳法中求证n=1时等式成立相似)。
递归模型 递归算法
例如,设计不带头结点的单链表的相关递归算法 f(L):大问题 L a1 a2 ... an
f(L->next):小问题
为什么在设计单链表的递归算法时不带头节点?
(1)求单链表中数据结点个数
递归模型如下: f(L)=0 当L=NULL
f(L)=f(L->next)+1
递归算法如下:
算法设计思路:
p a1 A 尾插法 B 尾插法 p b1 ...... bn ∧
例、设C={a1,b1,a2,b2,…,an,bn}为一线性表,采用带头 节点的hc单链表存放,设计一个就地算法,将其拆分为 两个线性表(它们都用单链表存放),使得: A={a1,a2,…,an},B={bn,bn-1,…,b1} C a1 A a1 B bn bn-1 ...... b1 ∧ a2 ...... an ∧ b1 ...... bn ∧
else return l;
} }
4、图算法设计
基于深度优先或广度优先遍历算法。

基于深度优先遍历算法的应用
例、假设图G采用邻接表存储,设计一个算法,判断顶 点u到v是否有简单路径。
解:从顶点u开始进行深度优先搜索,当搜索到顶点v时表 明从顶点u到顶点v有路径,即:
u u1 u2

v
用形参has(调用时其初值置为false)表示顶点uv是否 有路径。
递归模型: f(b,x,h)=0 f(b,x,h)=h f(b,x,h)=l 当b=NULL 当b->data=x 当l=f(b->lchild,x,h+1)≠0
f(b,x,h)=f(b->rchild,x,h+1) 其他
递归算法如下:
int Level(BTNode *b,ElemType x,int h) //找到值为x节点后h为其层次,否则为0 { if (b==NULL) return 0; else { l=Level(b->lchild,x,h+1); //在左子树中查找 if (l==0) //左子树中未找到时在右子树中查找 return Level(b->rchild,x,h+1); //空树时返回0 else if (b->data==x) return h; //找到节点时
递归算法如下: void traverse(Node *L) { if (L==NULL) return; printf("%d ",L->data); traverse(L->next); }
其他情况
(3)反向显示以L为首节点指针的单链表的所有节点值 递归模型如下:
f(L)不做任何事件
f(L)f(L->next);输出L->data; 递归算法如下: void traverseR(Node *L) { if (L==NULL) return; traverseR(L->next); printf("%d ",L->data); }
算法设计思路:
str1 p
l
str2
o
a
d i
n
g ∧
b
q
e 比较p==q
算法实现:
typedef struct Node { char data; struct Node *next; } SNODE; SNODE * Findlist(SNODE *str1,SNODE *str2) { int m,n; SNODE *p,*q; m=Listlen(str1); //求单链表str1的长度m n=Listlen(str2); //求单链表str2的长度n for (p=str1;m>n;m--) //若m大,则str1后移m-n+1个节点 p=p->next; for (q=str2;m<n;n--) //若n大,则str1后移n-m+1个节点 q=q->next; while (p->next!=NULL && p->next!=q->next) { p=p->next; //p、q两步后移找第一个指针值相等的节点 q=q->next; } return p->next; }
例、假设二叉树采用二叉链存储结构,设计一个算法Level() 求二叉树中值为x的节点的层次(假设节点值唯一)。
解:设 Level(b,x,h)返回二叉链b中data值为x的节点的层数, 其中h表示b所指节点的层数。 b
调用Level(b,x,1)返回x节 点的层数。
b
调用Level(b,x,1)返回x节 点的层数。

提炼数据结构解决问题的思路
数据结构解决问题的思路:
ADT = 逻辑结构+抽象运算(功能描述) 映射 运 算 实 现 ①问题描述
存储结构1

存储结构n
… 算法nm
②设计存储 结构
算法11
… 源自文库法1m
算法n1
③算法设计 ④算法分析
算法分析
最佳算法

归纳数据结构算法设计的通用性方法
1、单链表算法设计 2、递归算法设计 3、二叉树的算法设计 4、图算法设计
2012年全国高等学校计算机程序设 计类课程教学论坛 清华大学出版社
2012年3月●武汉
数据结构课程教学汇报
武汉大学计算机学院 李春葆
2012年3月25日
使用教材:
1
数据结构教程(第3版) 普通高等教育“十一五”国家级规划教材
2
成套教材:
数据结构教程(第3版) 数据结构教程(第3版)学习指导 数据结构教程(第3版)上机实验指导
当L=NULL
其他情况
和上例相比,仅 交换了两个语句
3、二叉树算法设计
b

b->lchild
f(b) 大问题
b->rchild
左子树
右子树
当f(b->lchild)和f(b->rchild) 可解时,f(b)就很容易求解 了。
f(b->lchild) 小问题1
f(b->rchild)
小问题2
例、 假设二叉树采用二叉链存储结构存储,试设计一个 算法,计算一棵给定二叉树的所有叶子节点个数。 解:计算一棵二叉树b中所有叶子节点个数的递归模型f(b) 如下: f(b)=0 若b=NULL f(b)=1 若*b为叶子节点
f(b)=f(b->lchild)+f(b->rchild)
其他情况
递归算法如下: int LeafNodes(BTNode *b) { int num1,num2; if (b==NULL) return 0; else if (b->lchild==NULL && b->rchild==NULL) return 1; else { num1=LeafNodes(b->lchild); num2=LeafNodes(b->rchild); return (num1+num2); } }
若*b为单分支节点
其他情况
递归算法如下:
int SSonNodes(BTNode *b) { if (b==NULL) return 0; else if (b->lchild!=NULL && b->rchild==NULL || b->lchild==NULL && b->rchild!=NULL) //为单分支节点 return SSonNodes(b->lchild)+ SSonNodes(b->rchild)+1; else //为双分支节点或叶子节点时 return SSonNodes(b->lchild)+ SSonNodes(b->rchild); }
3
作为成套教材已申报 “十二五”国家级规 划教材,目前被武汉大学审核通过。
数据结构课程教学汇报
清晰地讲授本课程的目的、地位和要求 提炼数据结构解决问题的思路 归纳数据结构算法设计的通用性方法 注重教学的多维性 强化实践教学环节

清晰地讲授本课程的目的、地位和要求
计算机科学课程体系(偏软)
后期课程 前期课程
相关文档
最新文档