二元树检索与周游算法设计与实现

[功能模块]

//二元树检索与周游算法的实现(VC++6.0调试通过)

#include <iostream>

#define n 11  //0号结点不用

typedef struct Node{

int num;          // 节点编号

struct Node *lch;

struct Node *rch;

}node,*BinTree;

 

struct Neighborhood {

int num;         // 节点编号

struct Neighborhood *next;

}*NeighborList[n];     // n个节点的邻接表,动态生成并初始化

 

//静态初始化n个节点的邻接矩阵

int NeighborMetrix[n][n]={ {0,0,0,0,0,0,0,0,0,0,0},{0,0,1,1,0,0,0,0,0,0,0},

{0,0,0,0,1,1,0,0,0,0,0},{0,0,0,0,0,0,1,1,0,0,0},{0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,0,1,1,0},{0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,1},

{0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0,0} };

 

void CreatBinTree(BinTree *T)       //先序动态生成二叉树

{ int data; 

  scanf("%d",&data);

  if(data==0) *T=NULL;       //输入0表示空树

  else

  {

         *T=(BinTree)malloc(sizeof(node));

         (*T)->num=data;

         CreatBinTree(&(*T)->lch);

         CreatBinTree(&(*T)->rch);

  } 

}

 

//动态生成并初始化邻接表

void CreatNeighborList(Neighborhood * NeighborList[])

{   int i,j;

    Neighborhood *p,*q;

    printf("初始化邻接表成功!/n");

       for(i=1;i<=10;i++)

       {           

              NeighborList[i]=(Neighborhood *)malloc(sizeof(Neighborhood));            

              NeighborList[i]->num=i;       //初始化邻接表行向量的值 

              NeighborList[i]->next=NULL;

       }    

       for(i=1;i<=10;i++)

       {

              printf("创建第 %d 个结点的邻接表(0表示NULL):",i);

              while(1)

              {

                     scanf("%d",&j);

                     if(j==0) break;  //该结点没有邻接结点

                     p=(Neighborhood *)malloc(sizeof(Neighborhood));                  

                     p->next=NULL;

                     p->num=j;

                     if(NeighborList[i]->next==NULL)

                            NeighborList[i]->next=p;  //指向第一个邻接结点

                     else

                     {

                            q=NeighborList[i]->next;

                            while(q->next!=NULL) q=q->next;  //找当前最后一个邻接结点

                            q->next=p;    //挂在当前结点的后面

                     }

              }

       }

}

 

//先根序周游并输出二元树的节点序列

void PreOrderTraverse(BinTree T)

{

       if(T!=NULL)

       {

              printf("%d/t",T->num);

              PreOrderTraverse(T->lch);

        PreOrderTraverse(T->rch);

       }

}

 

//中根序周游并输出二元树的节点序列

void InOrderTraverse(BinTree T)

{

       if(T!=NULL)

       {

              InOrderTraverse(T->lch);

              printf("%d/t",T->num);

        InOrderTraverse(T->rch);

       }

}

        

//后根序周游并输出二元树的节点序列

void PostOrderTraverse(BinTree T)

{

       if(T!=NULL)

       {

              PostOrderTraverse(T->lch);

              PostOrderTraverse(T->rch);

              printf("%d/t",T->num);

       }

}

 

//根据二元树的邻接表表示,按宽度优先检索输出二元树的节点序列

void BFS( Neighborhood * NeighborList[])

{

       int i,vo,visited[n],Q[n];

       int front=0,rear=0;

       Neighborhood *p;

       for(i=1;i<=10;i++) visited[i]=0;

       printf("输入开始宽度优先检索的结点:");

    scanf("%d",&vo);

       Q[rear++]=vo;

    printf("宽度优先检索的结点序列为:/n");

       printf("%d/t",vo);  //输出开始检索的结点

       visited[vo]=1;

       while(front!=rear)

       {

              vo=Q[front++];  //取队头元素

              p=NeighborList[vo]->next;

              while(p!=NULL)

              {

                     if(visited[p->num]==0) //如果未被访问过

                     {

                            Q[rear++]=p->num;   //入队列

                            printf("%d/t",p->num);  //访问该结点

                            visited[p->num]=1;

                     }

                     p=p->next;  //找下一个邻接结点

              }

       }

}

 

//根据二元树的邻接矩阵表示,按深度优先检索输出二元树的节点序列

void DFS(int NeighborMetrix[][n],int vo)

{

       int i;

    printf("%d/t",vo); //访问该结点

       for(i=1;i<=10;i++)

              if(NeighborMetrix[vo][i]==1) //如果邻接矩阵中有边

              {

                     NeighborMetrix[vo][i]=0; //访问后将该边置0                 

                     DFS(NeighborMetrix , i); //以找到的邻接结点继续检索

              }

}

 

// 释放动态分配的二元树节点空间  

void DeleteBinTree(BinTree T)

{

       if(T!=NULL) //通过后根序遍历来释放

       {

              DeleteBinTree(T->lch);

              DeleteBinTree(T->rch);

              free(T);

       }    

}

 

//释放动态分配的邻接表节点空间(通过再次宽度优先检索来释放)     

void DeleteNeighborList(Neighborhood * NeighborList[])

{

       int i,vo=1,visited[n],Q[n];

       int front=0,rear=0;

       Neighborhood *p,*q;

       for(i=1;i<=10;i++) visited[i]=0;    

       Q[rear++]=vo;

       visited[vo]=1;

       while(front!=rear)

       {

              vo=Q[front++];  //取队头元素

              p=NeighborList[vo]->next;                 

              free(NeighborList[vo]);   //每次释放队头元素的空间

              while(p!=NULL)

              {

                     if(visited[p->num]==0) //如果未被访问过

                     {

                            Q[rear++]=p->num;   //入队列                              

                            visited[p->num]=1;

                     }

                     p=p->next;  //找下一个邻接结点                    

              }

       }

}

 

void main()

{

       int vo;

       BinTree t;

       Neighborhood * NeighborList[n] ;

       printf("先序创建二元树(0表示NULL):/n");

       CreatBinTree(&t);

       printf("先根序周游二元树的节点序列为:/n");

    PreOrderTraverse(t);

       printf("中根序周游二元树的节点序列为:/n");

    InOrderTraverse(t);

       printf("后根序周游二元树的节点序列为:/n");

    PostOrderTraverse(t);

       printf("输入开始深度优先检索的结点:");

    scanf("%d",&vo);

       printf("深度优先检索的结点序列为:/n");

       DFS(NeighborMetrix , vo);

    printf("创建二元树的邻接表:/n");

    CreatNeighborList(NeighborList);   

    BFS(NeighborList);         

       printf("动态分配的二元树节点空间已释放!/n");

       DeleteBinTree(t);   

       printf("动态分配的邻接表节点空间已释放!/n");

       DeleteNeighborList(NeighborList);

}

 

 

[测试方案]

假设有以下二元树,可知: 
                         

先根序周游二元树的节点序列为:

1       2       4       5       8       9       3       6       7       10

中根序周游二元树的节点序列为:

4       2       8       5       9       1       6       3       7       10

后根序周游二元树的节点序列为:

4       8       9       5       2       6       10      7       3       1

深度优先检索的结点序列为:

1       2       4       5       8       9       3       6       7       10

宽度优先检索的结点序列为:

1       2       3       4       5       6       7       8       9       10

 

按以上数据进行测试,程序的运行结果如下:

 

      

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值