学习 严蔚敏讲数据结构笔记18
来源:互联网 发布:做淘宝仓库打包员累吗 编辑:程序博客网 时间:2024/05/25 12:21
遍历是所有非线性结构(包括二叉树,树,图和广义表)的操作基础
不同的应用需要应用不同的搜索路径
1. 深度优先搜索遍历 2广度优先搜索遍历
深度优先搜索遍历:
二叉树先序,中序,后序
树 先根,后根
图 先访问顶点,后访问顶点
广义表先遍历表头,先遍历表尾
深度优先搜索遍历算法的两种形式:递归,非递归
6.12已知L[i]和R[i](i=1,2,…n-1)分别指示二叉树中第i个结点的左孩子和右孩子结点,0表示空。试写判别结点u是否是结点v的子孙的算法。
分析:
1. u是否是结点v的子孙===从结点v出发遍历能否到达结点u;“访问”===判结点u是否是结点v的孩子
2. 给出的存储结构实质上是一个二叉链表
32_002
Status descendent(int L[], int R[], int u,int v)
{
if(u && v)
{
if(L[v] == u || R[v] == u)
return TRUE;
else if(descendent(L, R, u, L[v]))
return TRUE;
else
return descendent(L, R, u, R[v]);
}
else return FALSE;
}
6.19 编写递归算法:对于二叉树中每一个元素值为x的结点,删去以它为根的子树,并释放相应的空间。
分析:
1. 先序遍历二叉树的过程中查找每一个元素值为x的结点;
2. 修改其双亲结点的相应指针;
3. 释放以它为艮的子树上的所有结点,则应该后序遍历以它为根的子树
32_003
void Delete-X(BiTree &BT, ElemType x)
{
if(BT)
{
if(BT->data == x)
{
disp(BT);
BT = NULL;
}
else
{
Delete-X(BT->Lchild, x);
Delete-X(BT->Rchild, x);
}
}
}
6.22 编写一个算法:输出以二叉树表示的算数表达式,若该表达式中含有括号,则输出时应添上
分析:
1. 原表达式即为带括弧的中缀表达式,则此题应该进行中序遍历
2. 表达式求值应该进行后序遍历,则表明左、右子树的运算应该先于根结点的运算进行;因此,若左、右子树根的运算符的优先数低于根节点运算符的优先数,则应对左子树和右子树应加上括弧;
32_004
void Expression(BiTree T)
{
if(T)
{
if(precede(T->data, T->Lchild->data)
{
printf("(");
Expression(T->Lchild);
printf(")");
}
else
Expression(T->Lchild);
printf(T->data);
if(precede(T->data, T->Lchild->data))
}
}
6.24 编写算法完成下列操作:无重复地输出以孩子兄弟链表存储的树T中所有的边。输出的形式为(k1,k2),…,(ki,kj),..,其中,ki和kj为树结点中的结点标识。
分析:
在孩子兄弟链表中,哪一些结点是根的孩子?
33_001
void OutEdge(CStree T)
{
if(T)
{
p = T->firstchild;
while(p)
{
prntf(T->data, p->data);
OutEdge(p);
p = p->nextsibling;
}
}
}//先根遍历输出树中各条边
7.7 已知有向图和图中两个顶点u和v,试编写算法求有向图从u到v的所有简单路径。
33_002
void DFSearch(Graph G, int v, int s)
{
visited[v] = TRUE; //访问第v个顶点
Append(PATH, getVertex(v));
for(w = FirstAdjVex(v); w != 0; w = NextAdjVex(v))
OutPath(PATH);
if(! visited[w])
DFSearch(G, w, s);
visited[v] = FLASE;
}
深度优先搜索遍历的非递归形式的算法:一般情况下,需要一个“栈”保留一些信息
例如:遍历二叉树时,需要利用栈保留曾经路过的根结点(中序);或者保留尚未遍历的右子树的根结点(先序)以便从左子树返回时继续遍历右子树。
后序遍历二叉树的情况要复杂一些,由于根结点的访问在左、右子树的遍历之后,则不仅要保存结点的信息,还应保存“标志”。
反之,如果在存储结构中加上适当的信息,
6.15假设在二叉链表的结点中增设两个域;双亲域(parent)以指示其双亲结点;标识域(mark:0,1,2)以区分在遍历过程中到达该节点时应继续向左或向右访问该结点,试以此存储结构编写不用栈进行后序遍历的递归形式的算法。
Mark域的作用在于识别当前的状态:
Mark=0表示当前状态是对结点第一次访问
Mark=1表示当前状态是对结点第二次访问
Mark=2表示当前状态是对结点第三次访问
33_003
void postorder(BiTree T)
{
p = T;
while(p)
{
switch(p->mark)
{
case 0:
p->mark = 1;
if(p->Lchild)
{
p = p->Lchild;
}
break;
case 1:
p->mark = 2;
if(p->Rchild)
{
p = p->Rchild;
}
break;
case 2:
p->mark = 0;
//...
}
}
}
深度优先遍历图的非递归形式的算法
33_004
void DFS(Graph G, int v)
{
visited[v] = TRUE;
VisitFunc(v);
for(w = FirstAdjVex(G, v); w != 0; w = NextAdjVex(G, v, w))
if(! visited[w])
DFS(G, w);
}
可见,栈中保留的信息应该是:当前访问的顶点和它当前的邻接点
33_005
void DFS(Graph g, int v)
{
Visit(v);
visited[v] = TRUE;
...
while(! StackEmpty(S))
{
v = GetTop(S).vp;
w = GetTop(S),wp;
if(w)
{
if(! visited[w])
{
Visit(w);
visited[w] = TRUE;
...
}
else
{
w = NextAdj(G, v, w);
...
}
Pop(S);
}
}
}
广度优先搜索遍历的算法
33_006
void BFSTraverse(Graph G, Status(* Visit)(int v))
{
for(v = 0; v < G.vexnum; ++ v)
visited[v] = FALSE;
InitQueue(Q); //置空的辅助队列Q
for(v = 0; v < G.vexnum; ++v)
{
if(! visited[v])
{
//v尚未访问
visited[v] = TRUE;
Visit(v); //访问v
EnQueue(Q, v); //v入队列
while(! QueueEmpty(Q))
{
DeQueue(Q, u); //队列元素出队并置为u
for(w = FirstAdjVex(G, u); w != 0; w = NextAdjVex(G, u, w))
if(! visited[w])
{
visited[w] = TRUE;
Visit(w);
Enqueue(Q, w); //
}
}
}
}
}
6.20编写按层次顺序(同一层自左至右)遍历二叉树的算法
33_007
void BFSTraverse(BiTree T)
{
InitQueue(Q); //置空的辅助队列Q
if(T)
EnQueue(Q, T); //根结点入队列
while(! QueueEmpty(Q))
{
DeQueue(Q, p); //队头元素出队并置为p
Visit(p);
if(p->Lchild)
EnQueue(Q, p->Lchild); //左子树根入队列
if(p->Rchild)
EnQueue(Q, p->Rchild); //右子树根入队列
}
}
33_008
void BFSTraverse(CSTree T)
{
InitQueue(Q); //置空的辅助队列Q
if(T)
EnQueue(Q, T); //根结点入队列
while(! QueueEmpty(Q))
{
DeQueue(Q, p); //队头元素出队并置为p
Visit(p);
for(q = p->firstchild; !q; q = q->nextsibling)
EnQueue(Q, q); //子树根入队列
}
}
- 学习 严蔚敏讲数据结构笔记18
- 学习 严蔚敏讲数据结构笔记01
- 学习 严蔚敏讲数据结构笔记02
- 学习 严蔚敏讲数据结构笔记03
- 学习 严蔚敏讲数据结构笔记04
- 学习 严蔚敏讲数据结构笔记05
- 学习 严蔚敏讲数据结构笔记06
- 学习 严蔚敏讲数据结构笔记07
- 学习 严蔚敏讲数据结构笔记08
- 学习 严蔚敏讲数据结构笔记09
- 学习 严蔚敏讲数据结构笔记10
- 学习 严蔚敏讲数据结构笔记11
- 学习 严蔚敏讲数据结构笔记12
- 学习 严蔚敏讲数据结构笔记13
- 学习 严蔚敏讲数据结构笔记14
- 学习 严蔚敏讲数据结构笔记15
- 学习 严蔚敏讲数据结构笔记16
- 学习 严蔚敏讲数据结构笔记17
- 学习 严蔚敏讲数据结构笔记13
- 学习 严蔚敏讲数据结构笔记14
- 学习 严蔚敏讲数据结构笔记15
- 学习 严蔚敏讲数据结构笔记16
- 学习 严蔚敏讲数据结构笔记17
- 学习 严蔚敏讲数据结构笔记18
- 学习 严蔚敏讲数据结构笔记19
- 学习 严蔚敏讲数据结构笔记20
- 黑马训练营——java内存分配
- loadrunner常见问题汇总
- .net中获取周一、月初、月末、年初、年末
- C#索引器
- 串口通信
- Core Java Question List No2