为i和j(0
解:由二叉树顺序存储结构特点,可得到以下求离i和j的两个结点最近的公共祖先结点的算法:
ElemType Ancestor(ElemType A[],int i,int j) { }
int p=i,q=j; while (p!=q)
if (p>q) p=p/2; else q=q/2;
return A[p];
(2)已知一棵二叉树采用顺序方式存储在数组A[1..n]中。设计一个先序遍历的递归算法。
解:先序遍历树中结点的递归算法如下:
void PreOrder1(ElemType A[],int i,int n) { }
if (i if (A[i]!='#') { } //不为空结点时 //遍历左子树 printf(\ PreOrder1(A,2*i,n); //访问根结点 //遍历右子树 PreOrder1(A,2*i+1,n); (3)假设二叉树采用二叉链存储结构。设计一个算法求一棵非空二叉树中的最大结点 值。 解:求一个二叉树中的最大结点值的递归模型如下: f(bt)=bt->data 只有一个结点时 f(bt)=Max{f(bt->lchild),f(bt->rchild),bt->data} 其他情况 对应的算法如下: ElemType MaxNode(BTNode *bt) { } ElemType max,max1,max2; if (bt->lchild==NULL && bt->rchild==NUL) else { } max1=MaxNode(bt->lchild); //求左子树的最大结点值 max2=MaxNode(bt->rchild); //求右子树的最大结点值 max=bt->data; if (max1>max) max=max1; if (max2>max) max=max2; return(max); //求最大值 //返回最大值 return bt->data; (4)假设含有n个结点的二叉树采用二叉链存储结构。设计一个算法输出中序遍历序列中的第k(1≤i≤n)个结点值。 数据结构简明教程 解:对应的算法如下: int i=0; { } //i为全局变量 void Trav(BTNode *bt,int k) if (bt!=NULL) { } Trav(bt->lchild,k); i++; if (i==k) { } Trav(bt->rchild,k); //遍历右子树 printf(\return; //遍历左子树 (5)假设二叉树采用二叉链存储结构,设计一个算法Level()求二叉树中结点值为x的结点的层数。 解:对应的递归算法如下: int Level(BTNode *bt,ElemType x,int h) //调用h对应的实参置初值1 { } int l; if (bt==NULL) else { } l=Level(bt->lchild,x,h+1); if (l!=0) return l; //在左子树中未找到,再在右子树中查找 return(Level(bt->rchild,x,h+1)); else //在左子树中查找 return 0; return h; else if (bt->data==x) 上机实验题6 假设一棵二叉树采用二叉链存储结构,其中所有结点值均不相同。设计一个算法求从根结点到值为x的结点的路径。并用相关数据进行测试。 解:采用递归和层次遍历两种求解方法,对应的程序如下: #include void Path1(BTNode *bt,ElemType x,ElemType path[],int pathlen) { int i; if (bt!=NULL) { if (bt->data==x) //找到值为x的结点 } void Path2(BTNode *bt,ElemType x) { BTNode *p; ElemType path[MaxSize]; int i,d; struct { BTNode *s; int parent; //存放结点指针 //存放其双亲结点在qu中的下标 //qu存放队中元素 } { } else { } path[pathlen]=bt->data; pathlen++; //将当前结点放入路径中 //path中元素个数增1 printf(\从根结点到%c结点的路径: \for (i=0;i printf(\→\printf(\return; Path1(bt->lchild,x,path,pathlen); Path1(bt->rchild,x,path,pathlen); //递归遍历左子树 //递归遍历右子树 } qu[MaxSize]; rear++; qu[rear].s=bt; int front=-1,rear=-1; //队头队尾指针 //根结点进队 //根结点没有双亲,其parent置为-1 //队不空循环 //出队一个结点*p,它在qu中的下标为front //找到值为x的结点 qu[rear].parent=-1; while (front!=rear) { front++; p=qu[front].s; { } if (p->data==x) printf(\从根结点到%c结点的路径: \d=0; path[d]=p->data; i=qu[front].parent; while (i!=-1) { } printf(\for (i=d-1;i>=0;i--) printf(\→%c\printf(\ //*p有左孩子,将左孩子进队 d++; path[d]=qu[i].s->data; i=qu[i].parent; if (p->lchild!=NULL) 数据结构简明教程 } void main() { } BTNode *bt; ElemType path[MaxSize],x='I'; CreateBTree(bt,\printf(\解法1:\\n\Path1(bt,x,path,0); printf(\解法2:\\n\Path2(bt,x); //建立图6.14的二叉链 printf(\括号表示法:\ } { } if (p->rchild!=NULL) { } rear++; qu[rear].s=p->rchild; qu[rear].parent=front; //右孩子的双亲为qu[front]结点 //*p有右孩子,将右孩子进队 rear++; qu[rear].s=p->lchild; qu[rear].parent=front; //左孩子的双亲为qu[front]结点 练习题7 1. 单项选择题 (1)在一个图中,所有顶点的度数之和等于图的边数的( )倍。 A.1/2 B.1 C.2 D.4 答:C (2)在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的( )倍。 A.1/2 B.1 C.2 D.4 答:B (3)有8个顶点的无向图最多有( )条边。 A.14 B.28 C.56 D.112 答:B (4)有8个顶点的无向连通图最少有( )条边。 A.5 B.6 C.7 D.8 答:C (5)有8个顶点的有向完全图有( )条边。