二叉樹

    雖然對樹還是比較瞭解的,但是確實沒有認真的寫過一次完整的關於樹的代碼,這一次逼着自己寫了一些關於二叉樹的比較完整的操作,還有一些非遞歸的操作(如樹的遍歷)沒有寫呢,有機會會添加進去的。
    頭文件:
   
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>

#define MAX_QUEUE_SIZE 50

typedef char elemType;
typedef struct BiTNode
{
  elemType data;                         //值域
  struct BiTNode *lchild;     //指向左孩子的指針
  struct BiTNode *rchild;    //指向右孩子的指針
}BiTNode,*ptr_BiTNode;


void InitBinaryTree(ptr_BiTNode *ptr_bitree)
{//初始化一棵空二叉樹
  (*ptr_bitree)=NULL;
}


void CreateBinaryTree(ptr_BiTNode *ptr_bitree)
{     //按先序次序輸入二叉樹中結點的值(一個字符),空格字符表示空樹,
  //構造二叉鏈表表示的二叉樹
  elemType value;
  scanf("%c",&value);
  if(value==' ')
  {
    *ptr_bitree=NULL;
  }
  else
  {
    if(!((*ptr_bitree)=(BiTNode *)malloc(sizeof(BiTNode))))
    {
      printf("allocation failure.\n");
    }
    else
    {
      (*ptr_bitree)->data=value;                                            //生成根結點
      CreateBinaryTree(&((*ptr_bitree)->lchild));        //構造左子樹
      CreateBinaryTree(&((*ptr_bitree)->rchild));     //構造右子樹
    }
  }
}

void DestroyBinaryTree(ptr_BiTNode *ptr_bitree)
{//銷燬二叉樹
  if(*ptr_bitree)
  {//二叉樹存在
    if((*ptr_bitree)->lchild)
    {//銷燬左子樹
      DestroyBinaryTree(&((*ptr_bitree)->lchild));
    }
    if((*ptr_bitree)->rchild)
    {//銷燬右子樹
      DestroyBinaryTree(&((*ptr_bitree)->rchild));
    }
    free(*ptr_bitree);//釋放根節點指針
    (*ptr_bitree)=NULL;
  }
}

#define ClearBinaryTree DestroyBinaryTree

bool IsBinaryTreeEmpty(ptr_BiTNode ptr_bitree)
{//判斷二叉樹是否爲空
  if(ptr_bitree)
  {
    return false;
  }
  else
  {
    return true;
  }
}

int BinaryTreeDepth(ptr_BiTNode ptr_bitree)
{//返回樹的高度
  int l_depth,r_depth;
  if(ptr_bitree==NULL)
  {//樹空,深度爲0
    return 0;
  }
  else
  {
    if(ptr_bitree->lchild)
    {//左子樹不空
      l_depth=BinaryTreeDepth(ptr_bitree->lchild);
    }
    else
    {//左子樹爲空
      l_depth=0;
    }
    if(ptr_bitree->rchild)
    {//右子樹不空
      r_depth=BinaryTreeDepth(ptr_bitree->rchild);
    }
    else
    {//左子樹爲空
      r_depth=0;
    }
    return (l_depth>r_depth ? l_depth+1 : r_depth+1);
  }
}

elemType BinaryTreeRoot(ptr_BiTNode ptr_bitree)
{//獲取樹的根節點的值
  if(ptr_bitree)
  {
    return ptr_bitree->data;
  }
  else
  {
    printf("The binary_tree is empty.\n");
  }
}

elemType Value(ptr_BiTNode ptr_bitree,ptr_BiTNode ptr_node)
{//ptr_node是二叉樹中某個結點指針,返回該結點的值
  if(ptr_bitree)
  {//樹非空
    if(ptr_node)
    {//結點在樹中
      return ptr_node->data;
    }
    else
    {//結點不在樹中
      printf("The node is not in the binary_tree.\n");
    }
  }
  else
  {//樹空
    printf("The binary_tree is empty.\n");
  }
}

ptr_BiTNode Ptr_value(ptr_BiTNode ptr_bitree,elemType value)
{//二叉樹存在,value是樹中某結點的值,返回指向該結點的指針
  ptr_BiTNode ptr_node;
  if(ptr_bitree)
  {//樹非空
    if(ptr_bitree->data==value)
    {//檢查樹根
      return ptr_bitree;
    }
    else
    {
      if(ptr_node=Ptr_value(ptr_bitree->lchild,value))
      {//檢查左子樹
        return ptr_node;
      }
      if(ptr_node=Ptr_value(ptr_bitree->rchild,value))
      {//檢查右子樹
        return ptr_node;
      }
    }
    return NULL;//樹中不存在值爲value的結點
  }
  else
  {
    return NULL;
  }
}

void Assign(ptr_BiTNode ptr_bitree,elemType elem,elemType value)
{//樹存在,樹中存在某一結點值爲elem,將該結點賦值爲value
  ptr_BiTNode ptr_node;
  ptr_node=Ptr_value(ptr_bitree,elem);//獲取值爲elem的結點指針
  if(ptr_node)
  {//樹中存在值爲elem的結點
    ptr_node->data=value;
  }
  else
  {
    printf("The node doesn't in the binary_tree.\n");
  }
}

elemType Parent(ptr_BiTNode ptr_bitree,elemType elem)
{//樹不空,elem是樹中某結點值,返回該結點的父結點
  ptr_BiTNode ptr_node;
  ptr_BiTNode queue[MAX_QUEUE_SIZE];
  int front=0;
  int rear=0;
  if(ptr_bitree)
  {//樹非空,根結點指針入隊列
    queue[rear]=ptr_bitree;
    rear=(rear+1)%MAX_QUEUE_SIZE;
    if(ptr_bitree->data==elem)
    {//根節點沒有父節點
      printf("The root doesn't have a parent.\n");
      return NULL;
    }
  }
  while(front!=rear)
  {
    ptr_node=queue[front];
    front=(front+1)%MAX_QUEUE_SIZE;
    if(ptr_node->lchild && ptr_node->lchild->data==elem || ptr_node->rchild && ptr_node->rchild->data==elem)
    {//左或右孩子結點值爲elem,返回父節點
      return ptr_node->data;
    }
    else
    {//左右孩子的結點值不爲elem
      if(ptr_node->lchild)
      {//左孩子結點入隊列
        queue[rear]=ptr_node->lchild;
        rear=(rear+1)%MAX_QUEUE_SIZE;
      }
      if(ptr_node->rchild)
      {//右孩子結點入隊列
        queue[rear]=ptr_node->rchild;
        rear=(rear+1)%MAX_QUEUE_SIZE;
      }
    }
  }
}

elemType LeftChild(ptr_BiTNode ptr_bitree,elemType elem)
{//樹非空,elem是樹中某結點值,返回該結點的左孩子
  ptr_BiTNode ptr_node;
  if(ptr_bitree)
  {//樹非空
    ptr_node=Ptr_value(ptr_bitree,elem);//得到值爲elem的結點指針
    if(ptr_node && ptr_node->lchild)
    {
      return ptr_node->lchild->data;
    }
    else
    {
      return NULL;
    }
  }
}

elemType RightChild(ptr_BiTNode ptr_bitree,elemType elem)
{//樹非空,elem是樹中某結點值,返回該結點的右孩子
  ptr_BiTNode ptr_node;
  if(ptr_bitree)
  {//樹非空
    ptr_node=Ptr_value(ptr_bitree,elem);//得到值爲elem的結點指針
    if(ptr_node && ptr_node->rchild)
    {
      return ptr_node->rchild->data;
    }
    else
    {
      return NULL;
    }
  }
}

elemType LeftSibling(ptr_BiTNode ptr_bitree,elemType elem)
{//樹非空,elem爲樹中某結點的值,返回該結點的左兄弟
  elemType parent_value;
  ptr_BiTNode ptr_node;
  if(ptr_bitree)
  {//樹非空
    parent_value=Parent(ptr_bitree,elem);
    ptr_node=Ptr_value(ptr_bitree,parent_value);
    if(ptr_node->lchild && ptr_node->rchild && ptr_node->rchild->data==elem)
    {
      return ptr_node->lchild->data;
    }
    else
    {
      return NULL;
    }
  }
}

elemType RightSibling(ptr_BiTNode ptr_bitree,elemType elem)
{//樹非空,elem爲樹中某結點的值,返回該結點的右兄弟
  elemType parent_value;
  ptr_BiTNode ptr_node;
  if(ptr_bitree)
  {//樹非空
    parent_value=Parent(ptr_bitree,elem);
    ptr_node=Ptr_value(ptr_bitree,parent_value);
    if(ptr_node->lchild && ptr_node->rchild && ptr_node->lchild->data==elem)
    {
      return ptr_node->rchild->data;
    }
    else
    {
      return NULL;
    }
  }
}

bool InsertChild(ptr_BiTNode p,int LR,ptr_BiTNode c)
{//p爲樹中某結點指針,LR(0:左子樹,1:右子樹),c指向要插入的樹(c是一棵右子樹爲空的樹)
  //根據LR,確定將C所指向的樹插入爲p的左子樹還是右子樹,
  if(p)
  {
    if(LR==0)
    {//插入左子樹
      c->rchild=p->lchild;
      p->lchild=c;
    }
    else
    {//插入右子樹
      c->rchild=p->rchild;
      p->rchild=c;
    }
    return true;
  }
  return false;
}

bool DeleteChild(ptr_BiTNode p,int LR)
{//p指向樹中某結點,根據LR(0:左子樹,1:右子樹)的值決定刪除P所指結點的左子樹還是右子樹
  if(p)
  {
    if(LR==0)
    {//刪除左子樹
      DestroyBinaryTree(&(p->lchild));
    }
    else
    {//刪除右子樹
      DestroyBinaryTree(&(p->rchild));
    }
    return true;
  }
  return false;
}


bool print(elemType elem)
{
  printf("%2c",elem);
  return true;
}

bool PreOrderTraverse(ptr_BiTNode bitree,bool (* visit)(elemType elem))
{//前序遍歷
  if(bitree)
  {
    if(visit(bitree->data))
    {
      if(PreOrderTraverse(bitree->lchild,visit))
      {
        if(PreOrderTraverse(bitree->rchild,visit))
        {
          return true;
        }
      }
    }
    return false;
  }
  else
  {
    return true;
  }
}

bool InOrderTraverse(ptr_BiTNode bitree,bool (* visit)(elemType elem))
{//中序遍歷
  if(bitree)
  {
    if(InOrderTraverse(bitree->lchild,visit))
    {
      if(visit(bitree->data))
      {
        if(InOrderTraverse(bitree->rchild,visit))
        {
          return true;
        }
      }
    }
    return false;
  }
  else
  {
    return true;
  }
}

bool PostOrderTraverse(ptr_BiTNode bitree,bool (* visit)(elemType elem))
{//後序遍歷
  if(bitree)
  {
    if(PostOrderTraverse(bitree->lchild,visit))
    {
      if(PostOrderTraverse(bitree->rchild,visit))
      {
        if(visit(bitree->data))
        {
          return true;
        }
      }
    }
    return false;
  }
  else
  {
    return true;
  }
}

bool LevelOrderTraverse(ptr_BiTNode bitree,bool (* visit)(elemType elem))
{//層次遍歷
  ptr_BiTNode ptr_node;
  ptr_BiTNode queue[MAX_QUEUE_SIZE];
  int front=0;
  int rear=0;
  if(bitree)
  {//如果根指針不空,根指針入隊列
    queue[rear]=bitree;
    rear=(rear+1)%MAX_QUEUE_SIZE;
    while(front!=rear)
    {//隊列不空,隊首元素出隊
      ptr_node=queue[front];
      front=(front+1)%MAX_QUEUE_SIZE;
      visit(ptr_node->data);
      if(ptr_node->lchild)
      {//左孩子指針入隊列
        queue[rear]=ptr_node->lchild;
        rear=(rear+1)%MAX_QUEUE_SIZE;
      }
      if(ptr_node->rchild)
      {//右孩子指針入隊列
        queue[rear]=ptr_node->rchild;
        rear=(rear+1)%MAX_QUEUE_SIZE;
      }    
    }
    return true;
  }
  else
  {
    return false;
  }
}
    測試代碼:
   
#include "stdafx.h"
#include "binary_tree.h"
#include <conio.h>

int _tmain(int argc, _TCHAR* argv[])
{
  elemType root;
  elemType parent;
  elemType l_child;
  elemType r_child;
  elemType value1;
  elemType value2;
  elemType l_sibling;
  elemType r_sibling;
  int depth;
  ptr_BiTNode ptr_node;
  ptr_BiTNode p;
  ptr_BiTNode c;
  ptr_BiTNode ptr_bitree;
  InitBinaryTree(&ptr_bitree);
  if(IsBinaryTreeEmpty(ptr_bitree))
  {
    printf("The binary_tree is empty.\n");
  }
  else
  {
    printf("The binary_tree is not empty.\n");
  }

  printf("Let's create a new binary_tree.\nPlease enter the value of the binary_tree by pre_order.\n");
  CreateBinaryTree(&ptr_bitree);

  if(IsBinaryTreeEmpty(ptr_bitree))
  {
    printf("The binary_tree is empty.\n");
  }
  else
  {
    printf("The binary_tree is not empty.\n");
  }

  if(ptr_bitree)
  {
    printf("We have created a new binary_tree.\n");
  }

  printf("the PreOrderTraverse of the binary_tree:\n");
  if(PreOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  printf("the InOrderTraverse of the binary_tree:\n");
  if(InOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  printf("the PostOrderTraverse of the binary_tree:\n");
  if(PostOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  root=BinaryTreeRoot(ptr_bitree);
  printf("The root of the binary_tree is:%c\n",root);

  depth=BinaryTreeDepth(ptr_bitree);
  printf("The depth of the binary_tree is:%d\n",depth);

  ptr_node=Ptr_value(ptr_bitree,'F');
  value1=Value(ptr_bitree,ptr_node);
  Assign(ptr_bitree,value1,'M');
  value2=Value(ptr_bitree,ptr_node);
  printf("%c after assign is %c\n",value1,value2);

  printf("the PostOrderTraverse of the binary_tree:\n");
  if(PostOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  l_child=LeftChild(ptr_bitree,'B');
  if(l_child)
  {
    printf("The left_child of B is:%c\n",l_child);
  }
  else
  {
    printf("B doesn't have a left_child.\n");
  }

  r_child=RightChild(ptr_bitree,'E');
  if(r_child)
  {
    printf("The right_child of E is:%c\n",r_child);
  }
  else
  {
    printf("E doesn't have a right_child.\n");
  }

  parent=Parent(ptr_bitree,'G');
  if(parent)
  {
    printf("The parent of G is:%c\n",parent);
  }

  parent=Parent(ptr_bitree,'A');
  if(parent)
  {
    printf("The parent of A is:%c\n",parent);
  }
    
  l_sibling=LeftSibling(ptr_bitree,'C');
  if(l_sibling)
  {
    printf("The left_sibling of C is:%c\n",l_sibling);
  }
  else
  {
    printf("C doesn't have a left_sibling.\n");
  }

  r_sibling=RightSibling(ptr_bitree,'C');
  if(r_sibling)
  {
    printf("The right_sibling of C is:%c\n",r_sibling);
  }
  else
  {
    printf("C doesn't have a right_sibling.\n");
  }

  getchar();
  InitBinaryTree(&c);
  printf("Please enter the value of the binary_tree.\n");
  CreateBinaryTree(&c);
  if(c)
  {
    printf("We have created a inserted tree without right_child.\n");
  }

  depth=BinaryTreeDepth(c);
  printf("The depth of the binary_tree c is:%d\n",depth);

  p=Ptr_value(ptr_bitree,'D');
  if(InsertChild(p,0,c))
  {
    printf("Insert successfully.\n");
  }
  printf("the PostOrderTraverse of the binary_tree:\n");
  if(PostOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  p=Ptr_value(ptr_bitree,'I');
  if(DeleteChild(p,0))
  {
    printf("Delete_Child successfully.\n");
  }
  printf("the InOrderTraverse of the binary_tree:\n");
  if(InOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }

  printf("the LevelOrderTraverse of the binary_tree:\n");
  if(LevelOrderTraverse(ptr_bitree,print))
  {
    printf("\n");
  }
  getch();
  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章