数据结构习题整理(2.0)

16.现有程序

void pr(){

scanf("%c",&ch) ;

if (ch!='#') pr();

printf("%c" ,ch) ;

}

写出输入为abc#时,调用pr函数的输出结果。

 

 

17.试编写如下定义的递归函数的递归算法:

    g(m,n) = 0             当m=0,n>=0

g(m,n) = g(m-1,2n)+n   当m>0,n>=0

 

int G(int m, int n)

/* 如果 m<0 或 n<0 则返回 -1 */

{

    if(m<0||n<0)

    {

        return -1;

    }

    if(m==0&&n>=0)

    {

        return 0;

    }

    return G(m-1,2*n)+n;

}

18.给出满足下列条件的所有二叉树。

 

  1. 先序序列与后序序列相同;
  2. 中序序列与后序序列相同;
  3. 先序序列与中序序列相同;
  4. 中序序列与层次序列相同;

 

先序遍历二叉树的顺序是“根—左子树—右子树”,中序遍历“左子树—根—右子树”,后序遍历顺序是:“左子树—右子树―根”,根据以上原则,解答如下:

1)若先序序列与后序序列相同,则或为空树,或为只有根结点的二叉树。

2)若中序序列与后序序列相同,则或为空树,或为任一结点至多只有左子树的二叉树。

(3)若先序序列与中序序列相同,则或为空树,或为任一结点至多只有右子树的二叉树。

(4)若中序序列与层次遍历序列相同,则或为空树,或为任一结点至多只有右子树的二叉树

19.(1)n个结点的k叉树,若用具有k个child域的等长链结点存储树的一个结点,则空的child域有多少个?

假设有m个叶子节点 那么空域就是k*m,和你的理解是一致的

非叶子节点就是 N-m个,因为是K叉树 ,那么(N-m) * k 就是除根节点外的所有节点,除了根节点以外有N-1个节点,所以 (N-m) *k = N-1

k*m = N*k-(N-1)

20.一颗完全二叉树共有520个结点,该完全二叉树共有多少个叶子节点·度为1的结点和度为2的结点

完全二叉树的n1(结点为1)的结点数要么为0要么为1。

并根据二叉树的性质:n0=n2+1

则总节点数250=n0+n1+n2=n0+n1+n0-1=2n0+n1=521

则说明n1=1,那么就可以解出n0=260,n2=259.

所以答案就是:n0=260,n1=1,n2=259.

20.已知完全二叉树的第七层有10个结点,则整个二叉树的结点数为多少个?

这一题问的不严谨,原题应该是问最多的结点数,所以下面就已最多结点数计算

由于完全二叉树的第七层上最多有2^6=64个结点,现在第七层上有10个叶子结点,说明该完全二叉树共有8层,所以整个二叉树的结点最多是(2^7-1)+(64-10)*2=127+108=235

21.在不同的线索化二叉树中,空余指针个数分别是多少?

按照某种遍历方式对二叉树进行遍历,可以把二叉树中所有结点排序为一个线性序列.在该序列中,除第一个结点外每个结点有且仅有一个直接前驱结点;除最后一个结点外每一个结点有且仅有一个直接后继结点.这些指向直接前驱结点和指向直接后续结点的指针被称为线索(Thread),加了线索的二叉树称为线索二叉树.

按某种次序将二叉树线索化的实质是:按该次序遍历二叉树,在遍历过程中用线索取代空指针.

综上,第一个结点没有前驱,则其左指针为空,最后一个结点没有后继,则其右指针为空.

因此在不同的线索化二叉树中,空余指针个数应该是两个.

22.画出和下列已知序列对应的树T: 树的先根次序访问序列为GFKDAIEBCHJ; 树的后根次序访问序列为DIAEKFCJHBG。

树的先根序列为GFKDAIEBCHJ,后根序列为DIAEKFCJHBG,可以先转化成二叉树,再通过二叉树转换成树。注意二叉树的先根序列与等价树的先根序列相同,二叉树的中序序列对应着树的后根序列。

GFKDAIEBCHJ为所求二叉树的先序序列,DIAEKFCJHBG为二叉树的中序序列。通过观察先序序列,G为二叉树的根结点,再由中序序列,G的左子树序列为DIAEKFCJHB,右子为空。可以表示成如下形式:

G(DIAEKFCJHB,NULL)

对于子树先序序列为FKDAIEBCHJ,中序序列为DIAEKFCJHB,显然子树根为F。再由中序序列可以看到,F的左子树是DIAEK,右子树为CJHB。进一步表示成:

G(F(DIAEK,CJHB),NULL)

对于DIAEK(中序表示),先序为KDAIE,K为根,左子为DIAE,右子为空;对于CJHB,B为根,左子为CJH,右子为空。进一步表示成:

G(F(K(DIAE,NULL),B(CJH,NULL)),NULL)

G(F(K(D(NULL,IAE),NULL),B(C(NULL,JH),NULL)),NULL)

G(F(K(D(NULL,A(I,E)),NULL),B(C(NULL,H(J,NULL)),NULL)),NULL)

由此画出二叉树,进而画出树。

 

23.已知二叉树采用二叉链表方式存放,要求返回二叉树T的后序序列中的第一个结点的指针,是否可不用递归,且不用栈来完成请简述原因。

可以。

原因:后序遍历的顺序是“左子树―右子树―根结点”。因此,二叉树最左下的叶子结点是遍历的第一个结点。下面的语句段说明了这一过程(设P是二叉树根结点的指针)。

if (p! =NULL) {

while (p-> lchild! =NULL || p-> rchild! =NULL) {

while(p-> lchild! =NULL) p=p-> lchild;

if(p-> rchild! =NULL) p=p-> rchild;

}

}

return(p); //返回后序序列第一个结点的指针

24.已知一棵二叉树按顺序方式存储在数组A[1....N]中,设计算法求出下标分别为i和j的两个节点的最近的 公共祖先节点的值

 

#include "iostream.h"

const n = 10;

int findfather(int *a,int i,int j)

{

while(1)

{

if(i>j)

i=i/2;

else

j=j/2;

if(i == j)

return a[i-1];

}

}

void main()

{

int a[n]={1,2,3,4,5,6,7,8,9,10};

cout<<findfather(a,4,10);

}

25.假设二叉树采用二叉链表方式存储,root指向根结点,p所指结点和q所指结点为二叉树中的两个不同结点,且互不成为根到该结点的路径上的点,编程求解距离它们最近的共同祖先。

 #include<bits/stdc  .h>

  using namespace std;

  #define N 20

 typedef struct Tree{

 

        char data;

        struct Tree *LeftChild;

        struct Tree *RightChild;

}BiTNode , *BiTree;

 BiTree  Only(char *pre,char *in,int length){ //根据前序序列和中序序列唯一确定一个二叉树

                 BiTree  root;

                root=(BiTree)malloc(sizeof(BiTNode));

                root->data=*pre;

                 int index;

                if(length==0){ return 0;} //哇哦 这句话真是重中之重

                for(index=0;index<length;index  ){

                         if(root->data==in[index]){

                               break;

                          }

                 } //到了中序序列第几号元素:index==根节点==前序序列第一个元素

 

                 //递归 开始找根节点的左子树------的根节点

                root->LeftChild=Only(pre 1,in,index);

                  //递归 开始找根节点的右子树-------的根节点

                root->RightChild=Only(pre 1 index,in index 1,length-index-1);

                return root;

 }

 

bool Cover(BiTree root,char pt){

 

         if(root==NULL) { return false;}

         if(root->data==pt){

                return true;

         }else{

                 return Cover(root->LeftChild,pt)||Cover(root->RightChild,pt) ;

         }

 }

 BiTree SearchCommen(BiTree node,char pt1, char pt2){

 

 

             if(node==NULL){ return NULL;} //没有找到或者node压根就是个空的 返回null;

             if(node->data==pt1||node->data==pt2){ return NULL;}//一个元素和根节点元素撞了,另一个是子元素,二者没有共同祖先

 

             //两个元素都是正常的子节点的元素

             //先在根节点的左子树里面找两个元素

             bool t1=Cover(node->LeftChild,pt1);//leftchild   pt1

             bool t2=Cover(node->LeftChild,pt2);//leftchild  pt2

 

            if(t1!=t2) { return node;} //两个元素 一个在左边找到了 一个没找到 证明一左一右 所以祖先就是node

               else{

                 //t1=t2   如果都等于true 就是两个元素都在左子树这边 所以往下循环就好

                if(t1==true) { return SearchCommen(node->LeftChild,pt1,pt2);}

                 //t1=t2   如果都等于No 证明没有在左子树找到,那么就一定在右子树

                 if(t2==true) { return SearchCommen(node->RightChild,pt1,pt2);}

               }

 }

 

int main(){

    BiTree pt;

     /*假设二叉树采用二叉链表方式存储*/

     char pre[N];

      char in[N];

      char *preo=pre;

      char *ino=in;

      char ch1,ch2;

      int length;

      cout<<"输入前序序列";

      cin>>pre;

      cout<<endl;

      cout<<"输入中序序列";

      cin>>in;

      cout<<endl;

      length=strlen(pre);

      pt=Only(pre,in,length);

 

     cin>>ch1>>ch2;

      pt=SearchCommen(pt,ch1,ch2);

      if(pt){ cout<<pt->data;}

      else{ cout<<"NULL";}

 }

 

26.已知二叉树按照顺序方式存储,编写算法,计算二叉树中非叶子结点的数目

int NoLeafCount(Node *T)/*求二叉树中非叶子结点的数目*/

{

if(!T)

return 0; /*空树没有叶子*/

else if(!T->lchild && !T->rchild)

return 0; /*叶子结点*/

else

return (1 + NoLeafCount(T->lchild) + NoLeafCount(T->rchild));/*当前结点+左子树的非叶子数+右子树的非叶子数*/

}

猜你喜欢

转载自blog.csdn.net/mez_Blog/article/details/103453530