构造平衡二叉树例子

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

typedef struct
{
 unsigned int nKey;
}SElemTypeObj, *LPSELEMTYPEOBJ;

typedef LPSELEMTYPEOBJ ElemType;
typedef struct SBSTNode
{
 ElemType nData;  // Key
 int   nBF;  // 节点平衡因子
 struct SBSTNode* pLChild; // 左孩子节点
 struct SBSTNode* pRChild; // 又孩子节点
}SBSTNode, *LPSBSTNODE;

//===============================================================================================
/*
 单相右旋平衡处理,使用条件:在根结点左子树根结点的左子树上插入结点,形状如下:
   节点1(子数根结点,平衡因子从 1 变为 2 )
   /
  节点2
  /
 节点3(被插入的点)
*/
void R_Rotate(LPSBSTNODE* lpRootNode)
{
 LPSBSTNODE lpLChild  = (*lpRootNode)->pLChild;
 (*lpRootNode)->pLChild = lpLChild->pRChild;
 lpLChild->pRChild  = (*lpRootNode);
 (*lpRootNode)   = lpLChild;
}

//===============================================================================================
/*
 单相左旋平衡处理,使用条件:在根结点右子树根结点的右子树上插入结点,形状如下:
 节点1(子数根结点,平衡因子从 -1 变为 -2)
  /
  节点2
   /
   节点3(被插入的点)
*/
void L_Rotate(LPSBSTNODE* lpRootNode)
{
 LPSBSTNODE lpRChild  = (*lpRootNode)->pRChild;
 (*lpRootNode)->pRChild = lpRChild->pLChild;
 lpRChild->pLChild  = (*lpRootNode);
 (*lpRootNode)   = lpRChild;
}

//===============================================================================================
#define LESSTHAN (-1)
#define EQUATION (0)
#define GREATERTHAN (1)
/*
 判断两个 ElemType 类型的数据的大小,返回值:
 LESSTHAN : nData1 < nData2
 EQUATION : nData1 == nData2
 GREATERTHAN : nData1 > nData2
*/

int Compare(ElemType nData1, ElemType nData2)
{
 if (nData1->nKey == nData2->nKey)
  return EQUATION;
 else if (nData1->nKey > nData2->nKey)
  return GREATERTHAN;
 else
  return LESSTHAN;
}

//===============================================================================================
#define LH (+1)
#define EH (0)
#define RH (-1)

void LeftBalance(LPSBSTNODE* lpRootNode)
{
 LPSBSTNODE* pLChild = &((*lpRootNode)->pLChild);

 switch ((*pLChild)->nBF)
 {
 case LH:
  (*lpRootNode)->nBF = EH;
  (*pLChild)->nBF = EH;
  R_Rotate(lpRootNode);
  break;

 case RH:
  {
   LPSBSTNODE lpRChild = (*pLChild)->pRChild;

   switch (lpRChild->nBF)
   {
   case LH: (*lpRootNode)->nBF = RH; (*pLChild)->nBF = EH; break;
   case EH: (*lpRootNode)->nBF =  (*pLChild)->nBF = EH; break;
   case RH: (*lpRootNode)->nBF = EH; (*pLChild)->nBF = LH; break;
   }
   lpRChild->nBF = EH;
   L_Rotate(pLChild);
   R_Rotate(lpRootNode);
  }
  break;
 }
}

void RightBalance(LPSBSTNODE* lpRootNode)
{
 LPSBSTNODE* pRChild = &((*lpRootNode)->pRChild);

 switch ((*pRChild)->nBF)
 {
 case RH:
  (*lpRootNode)->nBF = EH;
  (*pRChild)->nBF = EH;
  L_Rotate(lpRootNode);
  break;

 case LH:
  {
   LPSBSTNODE lpLChild = (*pRChild)->pLChild;

   switch (lpLChild->nBF)
   {
   case LH: (*lpRootNode)->nBF = LH; (*pRChild)->nBF = EH; break;
   case EH: (*lpRootNode)->nBF =  (*pRChild)->nBF = EH; break;
   case RH: (*lpRootNode)->nBF = EH; (*pRChild)->nBF = RH; break;
   }
   lpLChild->nBF = EH;
   R_Rotate(pRChild);
   L_Rotate(lpRootNode);
  }
  break;
 }
}

//===============================================================================================
/*
 输入参数说明:
 lpSBSTNode : 平衡二叉树的根节点
 e   : 数据
*/

///

int InsertAVL(LPSBSTNODE* lpRootNode, ElemType nData, int* pTaller)
{
 int nRet = 1;
 if ((*lpRootNode) == 0)
 {
  (*lpRootNode)   = malloc(sizeof(SBSTNode));
  (*lpRootNode)->nData = nData;
  (*lpRootNode)->pLChild = 0;
  (*lpRootNode)->pRChild = 0;
  (*lpRootNode)->nBF  = EH;
  *pTaller   = 1;
 }
 else
 {
  if (Compare((*lpRootNode)->nData, nData) == EQUATION)
  {
   *pTaller = 0;
   nRet  = 0;
  }
  else if (Compare((*lpRootNode)->nData, nData) == GREATERTHAN)
  {
   if (InsertAVL(&((*lpRootNode)->pLChild), nData, pTaller) == 0)
    nRet = 0;
   else if (*pTaller == 1)
   {
    switch ((*lpRootNode)->nBF)
    {
    case LH:
     LeftBalance(lpRootNode);
     *pTaller = 0;
     break;

    case EH:
     (*lpRootNode)->nBF = LH;
     *pTaller = 1;
     break;

    case RH:
     (*lpRootNode)->nBF = EH;
     *pTaller = 0;
     break;
    }
   }
  }
  else
  {
   if (InsertAVL(&((*lpRootNode)->pRChild), nData, pTaller) == 0)
    nRet = 0;
   else if (*pTaller == 1)
   {
    switch ((*lpRootNode)->nBF)
    {
    case LH:
     (*lpRootNode)->nBF = EH;
     *pTaller = 0;
     break;

    case EH:
     (*lpRootNode)->nBF = RH;
     *pTaller = 1;     
     break;

    case RH:
     RightBalance(lpRootNode);
     *pTaller = 0;
     break;
    }
   }
  }
 }
 return nRet;
}

//===============================================================================================
/*
 中序遍历
*/
void Order(LPSBSTNODE lpRootNode)
{
 LPSBSTNODE lpChild = NULL;
 static int nIndex = 0;

 // 左孩子
 if (lpChild = lpRootNode->pLChild)
  Order(lpChild);

 // 自己
 printf("%2d:%5d/n", nIndex++, lpRootNode->nData->nKey);

 // 右孩子
 if (lpChild = lpRootNode->pRChild)
  Order(lpChild);
}

//===============================================================================================
// Test,用中序遍历来验证平衡二叉树
int main()
{
 SElemTypeObj Node1, Node2, Node3, Node4, Node5, Node6, Node7, Node8, Node9, Node10,
     Node11, Node12, Node13, Node14, Node15, Node16, Node17, Node18, Node19, Node20;
 LPSBSTNODE lpRootNode = 0;
 int Taller = 0;

 Node1.nKey = 13;
 Node2.nKey = 89;
 Node3.nKey = 37;
 Node4.nKey = 90;
 Node5.nKey = 45;
 Node6.nKey = 52;
 Node7.nKey = 46;
 Node8.nKey = 78;
 Node9.nKey = 28;
 Node10.nKey = 71;
 Node11.nKey = 76;
 Node12.nKey = 29;
 Node13.nKey = 56;
 Node14.nKey = 19;
 Node15.nKey = 82;
 Node16.nKey = 93;
 Node17.nKey = 48;
 Node18.nKey = 81;
 Node19.nKey = 95;
    Node20.nKey = 99;


 InsertAVL(&lpRootNode, &Node1, &Taller);
    InsertAVL(&lpRootNode, &Node2, &Taller);
 InsertAVL(&lpRootNode, &Node3, &Taller);
 InsertAVL(&lpRootNode, &Node4, &Taller);
 InsertAVL(&lpRootNode, &Node5, &Taller);
 InsertAVL(&lpRootNode, &Node6, &Taller);
 InsertAVL(&lpRootNode, &Node7, &Taller);
 InsertAVL(&lpRootNode, &Node8, &Taller);
 InsertAVL(&lpRootNode, &Node9, &Taller);
    InsertAVL(&lpRootNode, &Node10, &Taller);
 InsertAVL(&lpRootNode, &Node11, &Taller);
    InsertAVL(&lpRootNode, &Node12, &Taller);
 InsertAVL(&lpRootNode, &Node13, &Taller);
 InsertAVL(&lpRootNode, &Node14, &Taller);
 InsertAVL(&lpRootNode, &Node15, &Taller);
 InsertAVL(&lpRootNode, &Node16, &Taller);
 InsertAVL(&lpRootNode, &Node17, &Taller);
 InsertAVL(&lpRootNode, &Node18, &Taller);
 InsertAVL(&lpRootNode, &Node19, &Taller);
 InsertAVL(&lpRootNode, &Node20, &Taller);

 Order(lpRootNode);   
 return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值