二叉樹,二叉查找樹,平衡二叉樹原理及相關實現(二)

二叉查找樹:ios

    性質:對於樹中的每一個節點X,它的左子樹中全部關鍵字值小於X的關鍵字值,而它的右子樹中全部關鍵字值大於X的關鍵字。注意,這意味着該樹全部的元素能夠用某種統一的方式排序。數據結構

    如今給出一般對二叉查找樹進行的操做的簡要描述。(因爲樹的遞歸定義,一般是遞歸的編寫這些例程)。測試

  1.     初始化:將第一個元素初始化爲單節點樹spa

typedef struct TNode
{
    ElemType data;
    struct TNode *Lchild;
    struct TNode *Rchild;
}TreeNode, *BinaryTree; 
TNode* MakeEmpty(BinaryTree T)
{
    if(T != NULL)
    {
        MakeEmpty(T->Lchild);
       MakeEmpty(T->Rchild);
       free(T);
    }
       return NULL;
}

2.    Find操做:這一操做通常須要返回指向樹T中具備關鍵字X的結點指針,若是這樣的節點不存在則返回NULL。注意:測試的順序,關鍵的問題是首先要對是否爲空樹進行測試,不然就可能在NULL指針上兜圈子。其他的狀況應該使得最不可能的狀況安排在最後進行。指針

TNode* Find(BinaryTree T, ElemType e)
{
 if(T == NULL)
  return NULL;
 if( e < T->data)
  T->Lchild = Find(T->Lchild, e);
 else if(e > T->data)
  T->Rchild = Find(T->Rchild, e);
 else
  return T;
}

3.    Insert插入操做:進行插入操做的例程在概念上是很簡單的,爲了將X插入到樹T中,能夠像Find同樣沿着樹查找,若找到X,則什麼也不作,若沒有找到,就將X插入到遍歷路徑的最後一個點上。code

4.    Delete刪除操做:正如許多數據結構同樣,最困難的操做是刪除操做。一旦發現要刪除的節點,要考慮一下幾種狀況:排序

    1) 若是節點是一個葉子節點,則能夠被當即刪除。遞歸

    2) 若是節點有一顆子樹,則能夠在其父節點調整指針繞過要刪除的節點。ci

    3) 若是節點有兩棵子樹,通常的刪除策略是:用其右子樹的最小節點代替該節點的數據並遞歸的刪除那個節點it

//二叉排序樹的刪除操做,刪除節點以後獲得的還是二叉排序樹
TNode* DeleteBinaryTree(BinaryTree T, ElemType e)
{
 TNode *position;

 if(T == NULL)
 {
  cout << "error" << endl;
  exit(0);
 }
 else if(T->data > e)  //在樹中查找要刪除的元素
  T->Lchild = DeleteBinaryTree(T->Lchild, e);
 else if (T->data < e)
  T->Rchild = DeleteBinaryTree(T->Rchild, e);
 else      //找到該元素
 {
  if(T->Lchild && T->Rchild)  //若是要刪除的元素有左右子樹,則取右子樹的最小值來替換要刪除的節點
  {
   //position = FindMin(T->Rchild);
   position = T->Rchild;
   while(position != NULL)
   {
    position = position->Lchild;
   }
  }
  else      //刪除的節點有一個孩子,或沒有孩子
  {
   position = T;
   if(T->Lchild == NULL)
    T = T->Rchild;
   else if(T->Rchild == NULL)
    T = T->Rchild;
   free(position);
  }
 }
 return T;
}
//中序遍歷
void InOrder(BinaryTree T)
{
 if(T == NULL)
  return;
 if(T->Lchild != NULL)
  InOrder(T->Lchild);
 cout << T->data << " ";
 if(T->Rchild != NULL)
  InOrder(T->Rchild);
}

5. 二叉查找樹的遍歷:

1)前序遍歷:

 void PreorderTree(BinaryTree T)
{
 if(T == NULL)
  return;
 cout << T->data << " ";
 if(T->lchild != NULL)
  PreorderTree(T->lchild);
 if(T->rchild != NULL)
  PreorderTree(T->rchild);
}

2)中序遍歷

//中序遍歷
void InOrder(BinaryTree T)
{
 if(T == NULL)
  return;
 if(T->Lchild != NULL)
  InOrder(T->Lchild);
 cout << T->data << " ";
 if(T->Rchild != NULL)
  InOrder(T->Rchild);
}

3)後序遍歷

void PostorderTree(BinaryTree T)
{
 if(T == NULL)
  return;
 if(T->lchild != NULL)
  PostorderTree(T->lchild);
 if(T->rchild != NULL)
  PostorderTree(T->rchild);
 cout << T->data << " ";
}

4)層次遍歷 

 void LayerOrder(BinaryTree T)
{
 queue<TNode *> Q;
 TNode *p;
 p = T;
 if(T == NULL)
  cout << "這是一棵空樹!"<< endl;
 else 
 {
  Q.push(T);
  while(p != NULL && Q.empty() == 0)
  {
   p = Q.front();
   cout << p->data << " ";
   if(p->Lchild != NULL)
    Q.push(p->Lchild);
   if(p->Rchild != NULL)
    Q.push(p->Rchild);
   Q.pop();
   if(Q.empty())
    break;
   else
    p = Q.front();
  }
 }
}

 整體代碼:

#include<iostream>
using namespace std;

typedef int ElemType;
typedef struct TNode
{
 ElemType data;
 struct TNode *Lchild;
 struct TNode *Rchild;
}TreeNode, *BinaryTree;

TNode* Find(BinaryTree T, ElemType e)
{
 if(T == NULL)
  return NULL;
 if( e < T->data)
  T->Lchild = Find(T->Lchild, e);
 else if(e > T->data)
  T->Rchild = Find(T->Rchild, e);
 else
  return T;
}

//經過插入建立二叉查找樹
TNode* InsertBinaryTree(BinaryTree T, ElemType e)
{
 if(T == NULL)
 {
  T = new TNode();
  T->data = e;
  T->Lchild = NULL;
  T->Rchild = NULL;
 }
 else if(T->data > e)
 {
  T->Lchild = InsertBinaryTree(T->Lchild, e);
 }
 else if(T->data < e)
 {
  T->Rchild = InsertBinaryTree(T->Rchild, e);
 }
 else
 {
  cout << "該節點已存在" << endl;
  return NULL;
 }
 return T;
}

//二叉排序樹的刪除操做,刪除節點以後獲得的還是二叉排序樹
TNode* DeleteBinaryTree(BinaryTree T, ElemType e)
{
 TNode *position;

 if(T == NULL)
 {
  cout << "error" << endl;
  exit(0);
 }
 else if(T->data > e)  //在樹中查找要刪除的元素
  T->Lchild = DeleteBinaryTree(T->Lchild, e);
 else if (T->data < e)
  T->Rchild = DeleteBinaryTree(T->Rchild, e);
 else      //找到該元素
 {
  if(T->Lchild && T->Rchild)  //若是要刪除的元素有左右子樹,則取右子樹的最小值來替換要刪除的節點
  {
   //position = FindMin(T->Rchild);
   position = T->Rchild;
   while(position != NULL)
   {
    position = position->Lchild;
   }
  }
  else      //刪除的節點有一個孩子,或沒有孩子
  {
   position = T;
   if(T->Lchild == NULL)
    T = T->Rchild;
   else if(T->Rchild == NULL)
    T = T->Rchild;
   free(position);
  }
 }
 return T;
}
//中序遍歷
void InOrder(BinaryTree T)
{
 if(T == NULL)
  return;
 if(T->Lchild != NULL)
  InOrder(T->Lchild);
 cout << T->data << " ";
 if(T->Rchild != NULL)
  InOrder(T->Rchild);
}

int main()

 TNode *T, *p;
 p = NULL;
 T = NULL;
 int value;
 //while(cin >> value)
 //{
 // T = InsertBinaryTree(T, value);
 //}
 for(int i = 1; i < 8; i++)
  T = InsertBinaryTree(T, i);

 cout << "輸入要刪除的節點: "; int dele; cin >> dele; cout << dele << endl; p = DeleteBinaryTree(T, dele);  cout << "原來的元素序列:"; InOrder(T); cout << endl; cout << "刪除後獲得的序列:"; InOrder(p);  system("pause"); return 0;}

相關文章
相關標籤/搜索