遍歷二叉樹及其應用

主要代碼

/****************************************************
  @Title: 數據結構實驗
  @Name: <實驗6-3> 遍歷二叉樹及其應用
  @Object:
      [實驗目的]
          實現二叉樹的二叉鏈表存儲結構;
          實現先序、中序和後序遍歷二叉樹;
          遍歷二叉樹的應用:計算葉子結點,二叉樹深度等 
      [實驗提示]
          1. 在 bintree.h 中實現二叉樹的基本操作          
          2. 在 dsp0603.cpp 中編寫應用遍歷二叉樹的算法           
  @Include:
      bintree.h [*]
          二叉樹的二叉鏈表實現
  @Usage:
      請查看"TO-DO列表",根據要求完成代碼
  @Copyright: BTC 2004, Zhuang Bo
  @Author: Zhuang Bo
  @Date: 2004
  @Description:
*****************************************************/

#include <stdio.h>
#include <stdlib.h>

#define ElemType char //二叉樹中數據元素類型
#include "bintree.h"  //二叉樹的實現

//打印結點數據(作爲Visit函數)
Status print(char);
//計算二叉樹中葉子結點的個數
int LeafCount(BiTree bt);
//計算二叉樹的深度
int Deapth(BiTree bt);
//按縮進方式打印二叉樹
void PrintTreeIndent(BiTree bt, int indent);
//無返回值打印葉子個數
void LeafCount2(BiTree bt,  int &count);
//交換左右子樹
Status change(BiTree bt);

///////////////////////////////////////////////////////////
// 主程序 
void main()
{
    BiTree bt = 0;
    int count=0 ;
    //建立二叉樹
    printf("建立二叉樹(按先序輸入二叉樹中的結點,空格表示空樹)\n"); 
    if( CreateBiTree(bt)==ERROR ) {
        printf("ERROR: call CreateBiTree\n");
        system("pause");
        exit(1);
    }
    PrintTree(bt);

    //遍歷二叉樹
    printf("\n先序遍歷: ");
    if( PreOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call PreOrderTraverse\n"); 
    printf("\n中序遍歷: ");
    if( InOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call InOrderTraverse\n"); 
    printf("\n後序遍歷: ");
    if( PostOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call PostOrderTraverse\n"); 
    printf("\n按層遍歷: ");
    if( LevelOrderTraverse(bt,print)==ERROR )
        printf("ERROR: call LevelOrderTraverse\n"); 

    //二叉樹的應用
    printf("\n方法一求二叉樹中葉子結點的個數: %d\n", LeafCount(bt));
    LeafCount2(bt,count);
    printf("\n方法二求二叉樹中葉子結點的個數%d",count);
    printf("\n二叉樹的深度: %d\n", Deapth(bt));
    printf("\n按縮進形式打印:\n");
    PrintTreeIndent(bt,1);
    printf("\n交換左右子樹以後打印效果\n");
    change(bt);
    PrintTree(bt);
    //銷燬二叉樹 
    DestroyBiTree(bt); 
    system("pause"); //暫停以便查看結果 
}


///////////////////////////////////////////////////////////
// 函數實現

//打印結點數據
Status print(char ch)
{
    putchar(ch);
    return OK;
}

//計算二叉樹中葉子結點的個數
int LeafCount(BiTree bt)
{
    //-------------------------------------
    // TODO (#1#):計算二叉樹中葉子結點的個數
    int L,R;
    if(!bt) return 0;
    if(!(bt->lchild)&&!(bt->rchild)){
        return 1;
    }
    L=LeafCount(bt->lchild);
    R=LeafCount(bt->rchild);
    return L+R;

}
void LeafCount2(BiTree bt, int &count)
{
    //-------------------------------------
    // TODO (#1#):計算二叉樹中葉子結點的個數
    if(bt) {
    if(!(bt->lchild)&&!(bt->rchild)){
    count++;
    }
    LeafCount2(bt->lchild,count);
    LeafCount2(bt->rchild,count);
    }
}

//計算二叉樹的深度
int Deapth(BiTree bt)
{
    //-------------------------------------
    // TODO (#1#):計算二叉樹的深度
    int L,R;
    if(!bt){return 0;}
    L=Deapth(bt->lchild);
    R=Deapth(bt->rchild);
    return 1+max(L,R);
    //-------------------------------------
}

//按縮進方式打印二叉樹
void PrintTreeIndent(BiTree bt, int indent)
{
    //-------------------------------------
    // TODO (#1#):按縮進方式打印二叉樹
     int i;
      if (bt)
      { 
        for (i=1;  i<indent;  i++)  printf(" ");    //輸出indent個空格
        printf("%c\n", bt->data);
        PrintTreeIndent (bt->lchild, indent+3);
        PrintTreeIndent (bt->rchild,  indent+3);
       }
    //-------------------------------------
}
//交換左右子樹
Status change(BiTree bt){
    BiTree t;
    if(!bt){
        return ERROR;
    }
    t=bt->lchild;
    bt->lchild=bt->rchild;
    bt->rchild=t;
    change(bt->lchild);
    change(bt->rchild);
}

/*
  Name: 二叉鏈表實現二叉樹 
  Copyright: 
  Author: 
  Date:
  Description: 
*/

#ifndef BINTREE_H_INCLUDED
#define BINTREE_H_INCLUDED

#include <stdlib.h>
#include "ds.h"

//數據元素的缺省類型用char 
#ifndef ElemType
#define ElemType char
#define ELEMTYPE_TAG
#endif
/*下面使用TElemType如同ElemType*/
#define TElemType ElemType

///////////////////////////////////////////////////////////
// 二叉鏈表類型 
typedef struct BiTNode {
    TElemType data;
    struct BiTNode *lchild, *rchild; //左右孩子指針 
} BiTNode, *BiTree;


///////////////////////////////////////////////////////////
// 二叉鏈表的基本操作

//新建二叉鏈表結點
BiTree MakeNode(TElemType e, BiTree lch, BiTree rch)
{
    BiTree p = (BiTree)malloc(sizeof(BiTNode));
    p->data = e;
    p->lchild = lch;
    p->rchild = rch;
    return p;
}

//按  二叉樹中的結點值(字符)構造二叉樹 
Status CreateBiTree(BiTree &T)
{
    char ch;
    read(ch); // NOTE: 這裏用字符類型
    if( ch==' ' ) //空格代表空指針
        T = 0;
    else {
        //建立結點 
        //T = (BiTree)malloc(sizeof(BiTNode));
        //if(!T){
        //  exit(0);
        //}
        //T->data = ch; 
        //-------------------------------------
        // TODO (#1#):建立左子樹和右子樹
        T=MakeNode(ch, NULL, NULL);
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
        //-------------------------------------
    }
    return OK;
}

//銷燬二叉樹
Status DestroyBiTree(BiTree &T)
{
    //-------------------------------------
    // TODO (#1#): 銷燬二叉樹,釋放所有結點 
    return ERROR;
    //-------------------------------------
} 

//先序遍歷二叉樹T,對每個結點數據調用Visit函數
Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 先序遍歷二叉樹
    if(!T) return  OK;
    else{
    Visit(T->data);
    PreOrderTraverse(T->lchild, Visit);
    PreOrderTraverse(T->rchild, Visit);
    return OK;
    }
    return ERROR;
    //-------------------------------------
}

//中序遍歷二叉樹T,對每個結點數據調用Visit函數
Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 中序遍歷二叉樹
    if(!T) return  OK;
    else{
    InOrderTraverse(T->lchild, Visit);
    Visit(T->data);
    InOrderTraverse(T->rchild, Visit);
    return OK;
    }
    return ERROR;
    //-------------------------------------
}

//後序遍歷二叉樹T,對每個結點數據調用Visit函數
Status PostOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 後序遍歷二叉樹
    if(!T) return  OK;
    else{
    PostOrderTraverse(T->lchild, Visit);
    PostOrderTraverse(T->rchild, Visit);
    Visit(T->data);
    return OK;
    }
    return ERROR;
    //-------------------------------------
}

//按層次順序遍歷二叉樹T,對每個結點數據調用Visit函數
Status LevelOrderTraverse(BiTree T, Status(*Visit)(TElemType))
{
    //-------------------------------------
    // TODO (#1#): 按層次遍歷二叉樹
 BiTree  Q[100]; 
 int front=0,rear=0;
 if(!T)
 return ERROR;
 else
 {
  Visit(T->data);
  Q[rear]=T;  rear=(rear+1)%100;
  while(front!=rear){//隊列不爲空
  BiTree p=Q[front];
  front=(front+1)%100;
  if(p->lchild){
  Visit(p->lchild->data);
  Q[rear]=p->lchild; 
    rear=(rear+1)%100;
   }
  if(p->rchild){
   Visit(p->rchild->data);
   Q[rear]=p->rchild; 
   rear=(rear+1)%100;
   }
 }
 }
  return OK;
    //-------------------------------------

}

//以直觀方式打印二叉樹
void PrintTree(BiTree t, int level=0)
{
    int i;
    if(t) {
        PrintTree(t->rchild, level+1);
        for(i=0; i<level; i++) printf("    ");
        write(t->data); write('\n');
        PrintTree(t->lchild, level+1);
    }
}

//取消缺省類型的定義以免影響其它部分 
#ifdef ELEMTYPE_TAG
#undef ElemType
#undef ELEMTYPE_TAG
#endif

#endif //BINTREE_H_INCLUDED

演示效果圖

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章