1. 程式人生 > >【資料結構】---------二叉樹面試題(具體的所有實現)

【資料結構】---------二叉樹面試題(具體的所有實現)

實現二叉樹的相關的操作:

  • 先序遍歷樹(遞迴)
  • 中序遍歷樹(遞迴)
  • 後序遍歷樹(遞迴)
  • 層序遍歷樹
  • 建立一棵樹
  • 樹的銷燬
  • 樹的拷貝
  • 二叉樹中節點的個數
  • 二叉樹葉子節點的個數
  • 二叉樹第K層節點的個數
  • 樹的高度
  • 在二叉樹中查詢節點
  • 找當前節點的左子樹
  • 找當前節點的右子樹
  • 找當前節點的父節點
  • 非遞迴完成先序遍歷
  • 非遞迴完成中序遍歷
  • 非遞迴完成後序遍歷
  • 二叉樹的映象
  • 非遞迴完成二叉樹的映象
  • -

相關的操作的程式碼如下:

test.h的實現

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> #include <string.h> #define MAXSIZE 100 typedef char TreeNodeType; typedef struct TreeNode* SeqQType; typedef struct SeqQ{ SeqQType data[MAXSIZE];//定義了一個長度為100的佇列 size_t size;//記錄當前順序表的大小 size_t head; size_t tail; size_t capacity; }SeqQ; typedef struct
TreeNode* StackType; typedef struct SeqStack{ StackType* data;//使記憶體可以動態管理 int size;//棧元素的有效個數 int capacity;//棧預設的空間,data這段記憶體上所能容納的元素的個數 }SeqStack; typedef struct TreeNode{ struct TreeNode* lchild; struct TreeNode* rchild; TreeNodeType data; }TreeNode; void TreeInit(TreeNode** root,TreeNodeType value); void
PreOrder(TreeNode* root); void InOrder(TreeNode* root); void PostOrder(TreeNode* root); void LevelOrder(TreeNode* root); TreeNode* TreeCreate(TreeNodeType array[], size_t size,size_t *index, TreeNodeType null_node); TreeNode* TreeDestroy(TreeNode** root); TreeNode* TreeDestroy1(TreeNode** root); // 深複製樹,即克隆 TreeNode* TreeClone(TreeNode* root); // 求樹的結點數 size_t TreeSize1(TreeNode* root); size_t TreeSize2(TreeNode* root); // 求一棵樹的葉子節點數 size_t TreeLeafSize(TreeNode* root); // 求一棵樹第K層結點的個數 size_t TreeLevelSize(TreeNode* root, size_t K); // 求樹的高度 size_t TreeHight(TreeNode* root); // 在樹中查詢一個元素,並返回它的指標 TreeNode* TreeFind(TreeNode* root, TreeNodeType to_find); // 返回節點的左孩子節點 TreeNode* TreeLchild(TreeNode* root); // 返回節點的右孩子節點 TreeNode* TreeRchild(TreeNode* root); // 返回當前節點的父節點 TreeNode* TreeParent(TreeNode* root, TreeNode* node); void PreOrderByLoop(TreeNode* root);//非遞迴完成先序遍歷 void InOrderByLoop(TreeNode* root);//非遞迴完成中序遍歷 void PostOrderByLoop(TreeNode* root);//非遞迴完成後序遍歷 void TreeMirror(TreeNode* root);//二叉樹的映象(翻轉) void TreeMirrorByLoop(TreeNode* root);//非遞迴完成二叉樹的映象 int IsCompleteTree(TreeNode* root);//判斷一棵樹二叉樹是否是完全二叉樹

test.c的實現

#include "tree.h"


void TreeInit(TreeNode** root,TreeNodeType value)
{
    if(root==NULL)
    {
    return;
    }
    (*root)=malloc(sizeof(TreeNode));
    (*root)->lchild=NULL;
    (*root)->rchild=NULL;
    (*root)->data=value;
}

void PreOrder(TreeNode* root)
{
      if(root==NULL)
    {
    return;
    }
 //先訪問根節點
 printf("%c ",root->data);
 //再訪問左子樹
 PreOrder(root->lchild);
 //訪問右子樹
 PreOrder(root->rchild);
}


void InOrder(TreeNode* root)
{
    if(root==NULL)
    {
    return;
    }
    //訪問左子樹
    InOrder(root->lchild);
    //訪問根節點
    printf("%c ",root->data);
    //訪問右子樹
    InOrder(root->rchild);
}

void PostOrder(TreeNode* root)
{
    if(root==NULL)
    {
    return;
    }
    //先訪問左子樹
    PostOrder(root->lchild);
    //訪問右子樹
    PostOrder(root->rchild);
    //訪問根結點
    printf("%c ",root->data);
}

void SeqQInit(SeqQ* sq)
{
        if (sq == NULL)
    {
       return;
    }
    sq->size = 0;
    sq->head = 0;
    sq->tail = 0;
}

void SeqQResize(SeqQ* sq){
        if (sq == NULL){
        return;
    }
    if (sq->size <= MAXSIZE){
        return;
    }
    int size = MAXSIZE * 2 + 1;
    SeqQType* new = (SeqQType*)malloc(sizeof(SeqQType));
    int i =0;
    for (; i<sq->size; i++){
        new[i] = sq->data[i];
    }
    free(sq->data);
}

void SeqQPush(SeqQ* sq, SeqQType value)
{
        if (sq == NULL){
        return;
    }
    if (sq->size>=MAXSIZE)
    {
        SeqQResize(sq);
    return;
        }  
     sq->data[sq->tail++] = value;
      if (sq->tail >= MAXSIZE){
       sq->tail = 0;
      }
        ++sq->size;
}

void SeqQPop(SeqQ* sq){
        if (sq == NULL){
        return;
    }
    if (sq->size == 0){
        return;
    }
    ++sq->head;
    if (sq->head >= MAXSIZE){
        sq->head = 0;
    }
    --sq->size;
}
int  SeqQFront(SeqQ* sq, SeqQType* value){
        if (sq == NULL || value==NULL){
            return 0;
    }
        if (sq->size == 0){
            return 0;
        }
        *value = sq->data[(sq->head)];//注意在這裡考慮優先順序的問題
        return 1;
}


void LevelOrder(TreeNode* root)
{
    if(root==NULL)
    {
        return;
    }
     SeqQ sq;
     SeqQInit(&sq);
     SeqQPush(&sq,root);
    //將隊首元素進行入佇列
   while(1)
   {
    SeqQType front;
    int ret=SeqQFront(&sq,&front);
    //返回值為空時,說明樹已經訪問完了,迴圈結束
    if(ret == 0)
    {
    //若取隊首失敗,則為空,說明遍歷結束
    break;
    }
   //訪問隊首元素
    printf("%c ",front->data);
    SeqQPop(&sq);
    //入佇列左右子樹
    if(front->lchild!=NULL)
    {
    SeqQPush(&sq,front->lchild);
    }
    if(front->rchild!=NULL)
    {
    SeqQPush(&sq,front->rchild);
    }
   }
}

TreeNode*  TreeNodeCreate(TreeNodeType value)
{
   TreeNode* newnode=(TreeNode*)malloc(sizeof(TreeNode));
   newnode->data=value;
   newnode->lchild=NULL;
   newnode->rchild=NULL;
   return newnode;
}


TreeNode* TreeCreate(TreeNodeType array[], size_t size,size_t  *index, TreeNodeType null_node)
//根據先序遍歷的結構,帶有空結點的進行標記,構造成一棵樹,array[] 先序遍歷的結果 
//size 陣列中元素個數,null_node 陣列中空節點的特殊標記
{
    if(index==NULL)
    {
    return NULL;
    }
    //index表示當前取陣列中的哪一個元素

    //index不在有效的範圍內
    if(*index>=size){
    return NULL;
    }
    //如果該節點為空節點
    if(array[*index]==null_node)
    {
    return NULL;
    }
    //建立根結點
    TreeNode* newnode=TreeNodeCreate(array[*index]);
    //建立左子樹
    ++(*index);
    newnode->lchild=TreeCreate(array,size,index,null_node);
    //建立右子樹
    ++(*index);
    newnode->rchild=TreeCreate(array,size,index,null_node);
    return newnode;
} 

void DestroyNode(TreeNode** node)
{
    if(node==NULL || *node==NULL)
    return;
    free(*node);
    *node=NULL;
}

//方法一:使用的是後序便利的方法,不用額外的儲存節點資訊
TreeNode* TreeDestroy(TreeNode** root)
{
    if(root==NULL)
    {
    return NULL;
    }
    if(*root==NULL)
    {
    //空樹
    return NULL;
    }
    //遞迴的銷燬左子樹
    TreeDestroy(&(*root)->lchild);
    //遞迴的銷燬右子樹
    TreeDestroy(&(*root)->rchild);
    //銷燬根結點
    DestroyNode(root);
    *root=NULL;

}
 //方法二:使用先序中序遍歷,都要儲存它的父節點,這裡使用的是先序遍歷
 //要能夠保證我們找到左右子樹
  TreeNode* TreeDestroy1(TreeNode** root)
{
    if(root==NULL)
    {
    return NULL;
    }
    if(*root==NULL)
    {
    return NULL;
    }
    TreeNode* lchild=(*root)->lchild;
    TreeNode* rchild=(*root)->rchild;
    DestroyNode(root);
    TreeDestroy(&lchild);
    TreeDestroy(&rchild);
}

//樹的拷貝
//在這裡我們需要回顧的是拷貝分為兩種:
//①淺拷貝:兩個物件同時指向的是同一塊地址,(指標拷貝)資料之間會相互影響的
//記憶體不需要被修改
//②:深拷貝:就是將原有的物件的記憶體也將會複製一份(開銷比較大,資料之間不會受到影響的)
//其實還有一種就是我們在作業系統的過程中學到的寫時拷貝,它實際上是深淺拷貝兩隻進行結合的產物
TreeNode* TreeClone(TreeNode* root)
{
    if(root==NULL)
    {
    return NULL;
    }
    TreeNode* new_node=TreeNodeCreate(root->data);
    new_node->lchild=TreeClone(root->lchild);
    new_node->rchild=TreeClone(root->rchild);
    return new_node;
}


void _Treesize(TreeNode* root,size_t* size)
{
    if(root==NULL)
    {
    return ;
    }
    ++(*size);
    _Treesize(root->lchild,size);
    _Treesize(root->rchild,size);

}

//求二叉樹中結點的個數
 size_t TreeSize1(TreeNode* root)
{
    if(root==NULL)
    {
    return 0;
    }
    size_t size=0;
    _Treesize(root,&size);
    return size;
}
//遞迴的實現
size_t TreeSize2(TreeNode* root)
{
    if(root==NULL)
    {
    return 0;
    }
    return (1+TreeSize2(root->lchild)+TreeSize2(root->rchild));
}

//求二叉樹中葉子結點的個數
size_t TreeLeafSize(TreeNode* root)
 {
     if(root==NULL)
     {
     return 0;
     //空節點不是葉子結點
     }
     if(root->lchild==NULL && root->rchild==NULL)
     {
     //根結點也是葉子結點
     return 1;
     }
     return TreeLeafSize(root->lchild)+TreeLeafSize(root->rchild);
}


//求樹的第K層結點的個數
//我們轉換成的思路是求當前子樹的K-1層結點的個數
size_t TreeLevelSize(TreeNode* root, size_t K)
{
    if(root==NULL || K <1)
    {
    return 0;
    }
    if(K==1)
    {
    return 1;
    }
    return TreeLevelSize(root->lchild,K-1)+TreeLevelSize(root->rchild,K-1);
}


//求樹的高度
//我們可以看成是左右子樹的最大高度加1
size_t TreeHight(TreeNode* root)
{
    if(root==NULL)
    {
    return 0;
    }
    if(root->lchild==NULL && root->rchild==NULL)
    {
    return 1;
    }
    size_t lhight=TreeHight(root->lchild);
    size_t rhight=TreeHight(root->rchild);
    return 1+(lhight>rhight?lhight:rhight);
    //在這裡我們要注意優先順序的問題
}

 // 在樹中查詢一個元素,並返回它的指標
TreeNode* TreeFind(TreeNode* root, TreeNodeType to_find)
{
    if(root==NULL)
    {
    return NULL;
    }
    if(root->data==to_find)
    {
    return root;
    }
    else if(root->data<to_find)
    {
    TreeNode* lvalue=TreeFind(root->lchild,to_find);
    }
    return TreeFind(root->rchild,to_find);

}

// 返回節點的左孩子節點
TreeNode* TreeLchild(TreeNode* root)
{
    if(root==NULL)
    {
    return NULL;
    }
    return root->lchild;
}

 // 返回節點的右孩子節點
TreeNode* TreeRchild(TreeNode* root)
{
    if(root==NULL)
    {
    return NULL;
    }
    return root->rchild;
}

 // 返回當前節點的父節點,求child對應的父節點是誰
 TreeNode* TreeParent(TreeNode* root, TreeNode* node)
{
    if(root==NULL || node==NULL)
    {
    return NULL;
    }
    if(root->lchild==node || root->rchild==node)
    {
    return root;
    }
    TreeNode* lvalue=TreeParent(root->lchild,node);
    TreeNode* rvalue=TreeParent(root->rchild,node);
    return lvalue!=NULL?lvalue:rvalue;
}


void SeqStackInit(SeqStack* stack){
    if(stack==NULL){
    return;
    }
    stack->size=0;
    stack->capacity=1000;
    stack->data=(StackType*)malloc(stack->capacity*sizeof(StackType));
}

void SeqStackResize(SeqStack* stack)//擴容
{
    if(stack==NULL){
    return;
    }
    if((stack->size)<(stack->capacity)){
    return;
    }
    stack->capacity=stack->capacity*2+1;
StackType* new=(StackType*)malloc(stack->capacity*sizeof(StackType));
       int i=0;
       for(i=0;i<stack->size;i++){
           new[i]=stack->data[i];
       }
       free(stack->data);
       stack->data=new;

}

void SeqStackPush(SeqStack* stack,StackType value)//入棧
{
    if(stack==NULL){
    return;
    }
    if((stack->size)>=(stack->capacity)){
    SeqStackResize(stack);
    }
    stack->data[stack->size++]=value;
}

void SeqStackPop(SeqStack* stack)//出棧
{ 
    if(stack==NULL){
    return;
    }
    if(stack->size==0){
    return ;
    }//空棧
    --stack->size;
}

int SeqStackTop(SeqStack* stack,StackType* value)//取棧頂元素
{

    if(stack==NULL){
          return 0;
     }
      if(stack->size==0){
      return 0;//空棧
      }
      *value=stack->data[stack->size-1];
      return  1;
}


//採用非遞迴實現先序我們的主要想法是先把根結點進行入棧,迴圈開始
//取棧頂元素a,進行訪問(此處就是列印),然後將a的右子樹進行入棧
//在再將a的左子樹進行入棧,返回到迴圈繼續執行。
//
void PreOrderByLoop(TreeNode* root)
    //非遞迴完成先序遍歷
{
    if(root==NULL)
    {
    return ;
    }
    SeqStack stack;
    SeqStackInit(&stack);
    //1、先把根結點進行入棧
    SeqStackPush(&stack,root);
    TreeNode* cur=NULL;
    //2、迴圈開始的時候棧為空,
    //a)取棧頂元素為當前的元素
    while(SeqStackTop(&stack,&cur))
    {
    //b)出棧
    SeqStackPop(&stack);
    //c)訪問當前的元素(也就是列印當前的元素)
    printf("%c ",cur->data);
    //d)把當前元素的右子樹進行入棧
    if(cur->rchild!=NULL)
    {
        SeqStackPush(&stack,cur->rchild);
    }
        //e)把當前元素的左子樹進行入棧
    if(cur->lchild!=NULL)
    {
        SeqStackPush(&stack,cur->lchild);
    }
    }
}


void InOrderByLoop(TreeNode* root)//非遞迴完成中序遍歷
{
    if(root==NULL)
    {
    return ;
    }
    SeqStack stack;
    SeqStackInit(&stack);
    //1、定義cur指標指向根結點,將cur入棧
    TreeNode* cur=root;
    //2、迴圈的判定cur的是否為空,如果不為空就將cur入棧,
    //並且cur指向cur->lchild
    while(1)
    {
    while(cur!=NULL)
    {
        SeqStackPush(&stack,cur);
        cur=cur->lchild;
    }
    //3、如果cur為空,取棧頂元素,訪問出棧
    TreeNode* top=NULL;
        int ret=SeqStackTop(&stack,&top);
    if(ret==0)
    {
        //說明已經遍歷結束了,取不到棧頂元素,說明已經取完了
        return;
    }
    printf("%c ",top->data);
    SeqStackPop(&stack);
    //4、讓cur指向棧頂元素的右子樹,重複剛才的迴圈判定空的過程
    cur=top->rchild;
    }
}

 //我們後序遍歷也需要進行棧來維護,定義cur指向的是棧頂元素的右子樹
 //後序遍歷和中序遍歷有一個重要的差別就是取到的棧頂元素不能立即被訪問,
 //,需要滿足的條件有兩個:
 //1、當前的元素沒有右子樹
 //2、當前元素的右子樹已經被訪問過了(比較當前元素的右子樹是否和上一個結點相同
 //
 void PostOrderByLoop(TreeNode* root)//非遞迴完成後序遍歷
{
    if(root==NULL)
    {
    return ;
    }
    SeqStack stack;
    SeqStackInit(&stack);
//1、定義一個cur指向root的指標
   TreeNode* cur=root;
   TreeNode* pre=NULL;
   //2、迴圈的判定cur是否為空,要是cur不為空,我們
   //就將cur進行入棧,並且cur指向lchild
   while(1)
   {
       while(cur!=NULL)
       {
       SeqStackPush(&stack,cur);
       cur=cur->lchild;
       }
       //3、如果cur為空,迴圈的取棧頂元素
       TreeNode* top=NULL;
       int ret=SeqStackTop(&stack,&top);
       if(ret==0)
       {
       return;
       }

       //對棧頂元素進行判定,如果棧頂元素的右子樹和訪問的上一個元素
       //是同一個元素或者棧頂元素的右子樹為空,此時才能訪問棧頂元素
       //同時進行出棧
       if(top->rchild==NULL || top->rchild==pre)
       {
       printf("%c ",top->data);
       SeqStackPop(&stack);
       pre=top;
       }
       //如果不滿足以上的條件,cur指向的是棧頂元素右子樹
       //進行迴圈
       else
       {
       cur=top->rchild;
       }
   }
}


void swp(TreeNode** a,TreeNode** b)
{
    TreeNode* tmp=*a;
    *a=*b;
    *b=tmp;
}

 void TreeMirror(TreeNode* root)//二叉樹的映象(翻轉)
{
    if(root==NULL)
    {
    return ;
    }
        swp(&root->lchild,&root->rchild);
    TreeMirror(root->lchild);
    TreeMirror(root->rchild);
}

 void TreeMirrorByLoop(TreeNode* root)
    //非遞迴完成二叉樹的映象,這裡我們採用的是層序的方法
{
    if(root==NULL)
    {
    return;
    }
    SeqQ sq;
    SeqQInit(&sq);
    SeqQPush(&sq,root);
    TreeNode* cur=NULL;
    while(SeqQFront(&sq,&cur))
    {
    swp(&cur->lchild,&cur->rchild);
    SeqQPop(&sq);
    if(cur->lchild!=NULL)
    {
        SeqQPush(&sq,cur->lchild);
    }
    if(cur->rchild!=NULL)
    {
        SeqQPush(&sq,cur->rchild);
    }
    }
}
//判斷一棵樹是否是完全二叉樹
//層序遍歷,遍歷分為兩個階段
//階段一:任何一個節點同時具有左右子樹,一旦發現某個節點不是同時具備
//        a)當前節點只有右子樹,一定不是完全二叉樹
//        b)如果當前節點只有左子樹,進入階段二
//        c)如果當前節點沒有子樹,也進入階段二
//階段二:任何一個節點都必須沒有子樹
//遍歷結束後,若滿足所有條件,說明這個樹是完全二叉樹,否則,就不是
int IsCompleteTree(TreeNode* root)//判斷一棵樹二叉樹是否是完全二叉樹
{
 if(root == NULL){
             return 0;
             }
     SeqQ q;
     SeqQInit(&q);
     SeqQPush(&q,root);
    // 設一個標誌位表示是否進入階段二
     int flag = 0;
     TreeNode* cur = NULL;
     while(SeqQFront(&q,&cur)){
     if(flag == 0){
         //階段一的分支
     if(cur->lchild != NULL && cur->rchild != NULL){  
         //同時具有左右子樹  
         SeqQPush(&q,cur->lchild);
         SeqQPush(&q,cur->rchild);
     }
     else if(cur->lchild == NULL && cur->rchild != NULL){
         //只有右子樹沒有左子樹,一定不是完全二叉樹
         return 0;
     }else if(cur->lchild != NULL && cur->rchild == NULL){
         //只有左子樹沒有右子樹
         flag = 1;  
         SeqQPush(&q,cur->lchild);
     }else{
         //左右子樹都沒有
         flag = 1;
     }
     }
         //階段二的分支   
         if(cur->lchild == NULL && cur->rchild == NULL){
         ;
         }else{
         return 0;
         }//end 階段一和階段二的判定
     }//迴圈結束
     return 1;
}

/////////////////////////////////////////////////////
////////////////test.c//////////////////////////////
////////////////////////////////////////////////////

#define  TEST_HEADER  printf("\n===========%s=============\n",__FUNCTION__);

void test1()
{
    TEST_HEADER;
    TreeNode* root;
    TreeInit(&root,'a');
    //建立節點
    TreeNode* b=TreeNodeCreate('b');
    TreeNode* c=TreeNodeCreate('c');
    TreeNode* d=TreeNodeCreate('d');
    TreeNode* e=TreeNodeCreate('e');
    TreeNode* f=TreeNodeCreate('f');
    TreeNode* g=TreeNodeCreate('g');
    //構建樹
    root->lchild=b;
    root->rchild=c;


    b->lchild=d;
    b->rchild=e;
    e->lchild=g;
    c->rchild=f;
    printf("先序遍歷樹\n");
    PreOrder(root);
    printf("\n");
}

void test2()
{


    TEST_HEADER;
    TreeNode* root;
    TreeInit(&root,'a');
    //建立節點
    TreeNode* b=TreeNodeCreate('b');
    TreeNode* c=TreeNodeCreate('c');
    TreeNode* d=TreeNodeCreate('d');
    TreeNode* e=TreeNodeCreate('e');
    TreeNode* f=TreeNodeCreate('f');
    TreeNode* g=TreeNodeCreate('g');
    //構建樹
    root->lchild=b;
    root->rchild=c;
    b->lchild=d;
    b->rchild=e;
    e->lchild=g;
    c->rchild=f;
    printf("中序遍歷樹\n");
    InOrder(root);
    printf("\n");
}

void test3()
{

    TEST_HEADER;
    TreeNode* root;
    TreeInit(&root,'a');
    //建立節點
    TreeNode* b=TreeNodeCreate('b');
    TreeNode* c=TreeNodeCreate('c');
    TreeNode* d=TreeNodeCreate('d');
    TreeNode* e=TreeNodeCreate('e');
    TreeNode* f=TreeNodeCreate('f');
    TreeNode* g=TreeNodeCreate('g');
    //構建樹
    root->lchild=b;
    root->rchild=c;
    b->lchild=d;
    b->rchild=e;
    e->lchild=g;
    c->rchild=f;
    printf("後序遍歷樹\n");
    PostOrder(root);
    printf("\n");
}

void test4()
{

    TEST_HEADER;
    TreeNode* root;
    TreeInit(&root,'a');
    //建立節點
    TreeNode* b=TreeNodeCreate('b');
    TreeNode* c=TreeNodeCreate('c');
    TreeNode* d=TreeNodeCreate('d');
    TreeNode* e=TreeNodeCreate('e');
    TreeNode* f=TreeNodeCreate('f');
    TreeNode* g=TreeNodeCreate('g');
    //構建樹
    root->lchild=b;
    root->rchild=c;
    b->lchild=d;
    b->rchild=e;
    e->lchild=g;
    c->rchild=f;
    printf("層序遍歷樹\n");
    LevelOrder(root);
    printf("\n");
}

void testtreecreate()
{

    TEST_HEADER;
   // TreeNode* root;
   // TreeInit(&root,'a');
    TreeNodeType array[]="abd##eg###c#f##";
    size_t size=strlen(array);
    size_t index=0;
    TreeNodeType null_node='#';
    TreeNode* tmp=TreeCreate( array, size,&index,null_node);
    PreOrder(tmp);
    printf("\n");

    InOrder(tmp);
    printf("\n");

    PostOrder(tmp);
    printf("\n");

    LevelOrder(tmp);
    printf("\n");
}


void testtreedestroy()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size1=strlen(arr);
    size_t index=0;
    TreeNodeType null_node='#';
    TreeNode* p=TreeCreate( arr, size1,&index,null_node);
    PreOrder(p);
    printf("\n");

    printf("銷燬之後的結果為: \n");   
    TreeDestroy(&p);
    printf("\n");

    PreOrder(p);
    printf("\n");

}

void testclone()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    TreeNode* new_node= TreeClone(root);

    printf("對建立好的樹進行先中後遍歷:\n");
    PreOrder(new_node);
    printf("\n");

    InOrder(new_node);
    printf("\n");


    PostOrder(new_node);
    printf("\n");


}

void testtreesize()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);

    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    size_t tmp=TreeSize2(root);
    printf("%d\n",tmp);
}

void testleafsize()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    size_t tmp=TreeLeafSize(root);
    printf("%d\n",tmp);
}

void testlevelsize()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    size_t  m=4;
    size_t tmp=TreeLevelSize(root,4);
    printf("%d\n",tmp);
}

void testtreehight()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    size_t tmp=TreeHight(root);
    printf("%d\n",tmp);
}

void testfind()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("查詢元素‘c'是不是存在樹中: \n");
    TreeNode* tmp=TreeFind(root,'c');
    printf("%c\n",tmp->data);
}

void testlchild()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    TreeNode* value=TreeLchild(root);
    printf("%c\n",value->data);
}

void testrchild()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    TreeNode* tmp=TreeRchild(root);
    printf("%c\n",tmp->data);
}

void testparent()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    TreeNode* ret= TreeParent(root, root->lchild->rchild);
    printf("%c\n",ret->data);
}

void testpreorderbyloop()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("非遞迴的實現先序遍歷: \n");
    PreOrderByLoop(root);
    printf("\n");
}


void testinorder()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("非遞迴的實現中序遍歷: \n");
    InOrderByLoop(root);
    printf("\n");
}

void testpostorderloop()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("非遞迴的實現後序遍歷: \n");
    PostOrderByLoop(root);
    printf("\n");
}

void testtreemirror1()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("非遞迴的實現映象: ");
    TreeMirror(root);
    printf("\n");
    printf("先序列印映象後的樹: ");
    PreOrder(root);
    printf("\n");
    printf("中序列印映象後的樹:");
    InOrder(root);
    printf("\n");
    printf("後序列印映象後的樹:");
    PostOrder(root);
    printf("\n");
    printf("層序列印映象後的樹:");
    LevelOrder(root);
    printf("\n");
}

void testtreemirror2()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);
    printf("非遞迴的實現映象: ");
    TreeMirrorByLoop(root);
    printf("\n");
    printf("先序列印映象後的樹: ");
    PreOrder(root);
    printf("\n");
    printf("中序列印映象後的樹:");
    InOrder(root);
    printf("\n");
    printf("後序列印映象後的樹:");
    PostOrder(root);
    printf("\n");
    printf("層序列印映象後的樹:");
    LevelOrder(root);
    printf("\n");
}

void testiscomplete()
{

    TEST_HEADER;
    TreeNodeType arr[]="abd##eg###c#f##";
    size_t size=strlen(arr);
    size_t index=0;//當我們傳入的是*index,就不能實現這種
    TreeNodeType null_node='#';
    TreeNode* root=TreeCreate( arr, size,&index,null_node);

    int value=IsCompleteTree(root);
    printf("IsCompleteTree expect is 0,actual is %d\n",value);
}


int main()
{
    test1();
    test2();
    test3();
    test4();
    testtreecreate();
    testtreedestroy();
    testclone();
    testtreesize();
    testleafsize();
    testlevelsize();
    testtreehight();
    testfind();
    testlchild();
    testrchild();
    testparent();
    testpreorderbyloop();
    testinorder();
    testpostorderloop();
    testtreemirror1();
    testtreemirror2();
    testiscomplete();
    return 0;
}