二叉树,二叉查找树,平衡二叉树原理及相关实现(二)

二叉查找树: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;}

相关文章
相关标签/搜索