平衡二叉树

本文介绍如何从输入的小写字母字符串构建平衡二叉排序树,并输出其先序、中序、后序遍历结果及左旋转90度后的结构。通过具体实例展示算法实现细节。
成绩 10 开启时间 2017年11月6日 星期一 14:45
折扣 0.8 折扣时间 2017年11月28日 星期二 23:55
允许迟交 关闭时间 2018年01月8日 星期一 23:55

    程序输入一个字符串(只包含小写字母),请按照字符的输入顺序建立平衡二叉排序树,并分别输出二叉树的先序序列、中序序列和后序序列,最后输出该二叉树向左旋转 90 度后的结构,如,下图所表示的二叉树,

tu

向左旋转 90 度后,以每层向里缩进 4 个空格的方式输出,输出结果为:

        i
    g
        f
a
        d
    c
        b

输入:agxnzyimk

输出:
Preorder: xigamknzy
Inorder: agikmnxyz
Postorder: agknmiyzx
Tree:
    z
        y
x
            n
        m
            k
    i
        g
            a

  测试输入关于“测试输入”的帮助 期待的输出关于“期待的输出”的帮助 时间限制关于“时间限制”的帮助 内存限制关于“内存限制”的帮助 额外进程关于“{$a} 个额外进程”的帮助
测试用例 1 以文本方式显示
  1. agxnzyimk↵
以文本方式显示
  1. Preorder: xigamknzy↵
  2. Inorder: agikmnxyz↵
  3. Postorder: agknmiyzx↵
  4. Tree:↵
  5.     z↵
  6.         y↵
  7. x↵
  8.             n↵
  9.         m↵
  10.             k↵
  11.     i↵
  12.         g↵
  13.             a↵
1秒 64M 0
测试用例 2 以文本方式显示
  1. asdfghjkl↵
以文本方式显示
  1. Preorder: gdafjhlks↵
  2. Inorder: adfghjkls↵
  3. Postorder: afdhksljg↵
  4. Tree:↵
  5.             s↵
  6.         l↵
  7.             k↵
  8.     j↵
  9.         h↵
  10. g↵
  11.         f↵
  12.     d↵
  13.         a↵
1秒 64M 0
测试用例 3 以文本方式显示
  1. abcdefghi↵
以文本方式显示
  1. Preorder: dbacfehgi↵
  2. Inorder: abcdefghi↵
  3. Postorder: acbegihfd↵
  4. Tree:↵
  5.             i↵
  6.         h↵
  7.             g↵
  8.     f↵
  9.         e↵
  10. d↵
  11.         c↵
  12.     b↵
  13.         a↵
1秒 64M 0

#include<stdio.h> 
#include<stdlib.h> 
 
typedef struct node 
{ 
    int height; 
    char data; 
 struct node* lchild; 
   struct node* rchild; 
}AVLNode,*AVLTree; 
 
int Height(AVLTree T) 
{ 
   if (!T) return -1; 
 return T->height; 
} 
 
AVLTree Simpleleft(AVLTree k2) 
{ 
   AVLTree k1; 
    k1 = k2->lchild; 
    k2->lchild = k1->rchild; 
 k1->rchild = k2; 
 
   k1->height = Max(Height(k1->lchild), Height(k1->rchild)) + 1; 
 k2->height = Max(Height(k2->lchild), Height(k2->rchild)) + 1; 
 return k1; 
} 
 
AVLTree Simpleright(AVLTree k2) 
{ 
    AVLTree k1; 
    k1 = k2->rchild; 
    k2->rchild = k1->lchild; 
 k1->lchild = k2; 
 
 
  k1->height = Max(Height(k1->lchild), Height(k1->rchild)) + 1; 
 k2->height = Max(Height(k2->lchild), Height(k2->rchild)) + 1; 
 return k1; 
} 
 
AVLTree Doubleleft(AVLTree K3) 
{ 
 K3->lchild = Simpleright(K3->lchild); 
    return Simpleleft(K3); 
} 
 
AVLTree Doubleright(AVLTree K3) 
{ 
    K3->rchild = Simpleleft(K3->rchild); 
 return Simpleright(K3); 
} 
 
int Max(int a, int b) 
{ 
 return a > b ? a : b; 
} 
 
AVLTree Insert(char data, AVLTree T) 
{ 
 if (T == NULL) 
 { 
      T = (AVLTree)malloc(sizeof (struct node)); 
     T->data = data; T->height = 0; T->lchild = T->rchild = NULL; 
   } 
  else if (data < T->data) 
 { 
      T->lchild = Insert(data, T->lchild); 
     if (Height(T->lchild) - Height(T->rchild) == 2) 
      if (data<T->lchild->data) 
         T = Simpleleft(T); 
     else 
           T = Doubleleft(T); 
 } 
  else if (data>T->data) 
   { 
      T->rchild = Insert(data, T->rchild); 
     if (Height(T->rchild) - Height(T->lchild) == 2) 
      if (data>T->rchild->data) 
         T = Simpleright(T); 
        else 
           T = Doubleright(T); 
    } 
  T->height = Max(Height(T->lchild), Height(T->rchild)) + 1; 
    return T; 
} 
 
void Pre(AVLTree t) 
{ 
 if (t) 
 { 
      printf("%c", t->data); 
      Pre(t->lchild); 
     Pre(t->rchild); 
 } 
} 
 
void In(AVLTree t) 
{ 
  if (t) 
 { 
      In(t->lchild); 
      printf("%c", t->data); 
      In(t->rchild); 
  } 
} 
 
void Post(AVLTree t) 
{ 
    if (t) 
 { 
      Post(t->lchild); 
        Post(t->rchild); 
        printf("%c", t->data); 
  } 
} 
 
void PrintAVLTree(AVLTree t,int depth) 
{ 
  if (t) 
 { 
       
       if (t->rchild) 
          PrintAVLTree(t->rchild, depth + 1); 
     for (int i = 0; i < depth; i++) 
         printf("    "); 
        printf("%c\n", t->data); 
        if (t->lchild) 
          PrintAVLTree(t->lchild,depth+1); 
    } 
} 
 
int main() 
{ 
  //freopen("1.txt", "r", stdin); 
    char tree[50]; 
 gets(tree); 
    AVLTree root = NULL; 
   for (int i = 0; tree[i]; i++) 
  { 
      root=Insert(tree[i], root); 
    } 
  printf("Preorder: "); 
  Pre(root); printf("\n"); 
   printf("Inorder: "); 
   In(root); printf("\n"); 
    printf("Postorder: "); 
 Post(root); printf("\n"); 
  printf("Tree:\n"); 
 PrintAVLTree(root,0); 
  return 0; 
} 


1本程序在vc++6.0编译通过能正常运行。 2主界面 程序已经尽量做到操作简便了,用户只需要根据提示一步步进行操作就行了。 六思考和总结: 这个课程设计的各个基本操作大部分都在我的综合性实验中实现了,所以做这个主要攻克插入和删除这两个算法!其中插入在书本上已经有了,其中的右平衡算法虽然没有给出,但通过给出的左平衡算法很容易就可以写出右平衡算法。所以最终的点就在于删除算法的实现!做的过程中对插入算法进行了非常非常多次的尝试!花了非常多的时间,这其中很多时候是在对程序进行单步调试,运用了VC6。0的众多良好工具,也学到了很多它的许多好的调试手段。 其中删除算法中最难想到的一点是:在用叶子结点代替要删除的非叶子结点后,应该递归的运用删除算法去删除叶子结点!这就是整个算法的核心,其中很强烈得体会到的递归的强大,递归的最高境界(我暂时能看到的境界)! 其它的都没什么了。选做的那两个算法很容易实现的: 1合两棵平衡二叉排序树:只需遍历其中的一棵,将它的每一个元素插入到另一棵即可。 2拆分两棵平衡二叉排序树:只需以根结点为中心,左子树独立为一棵,右子树独立为一棵,最后将根插入到左子树或右子树即可。 BSTreeEmpty(BSTree T) 初始条件:平衡二叉排序树存在。 操作结果:若T为空平衡二叉排序树,则返回TRUE,否则FALSE. BSTreeDepth(BSTree T) 初始条件:平衡二叉排序树存在。 操作结果:返回T的深度。 LeafNum(BSTree T) 求叶子结点数,非递归中序遍历 NodeNum(BSTree T) 求结点数,非递归中序遍历 DestoryBSTree(BSTree *T) 后序遍历销毁平衡二叉排序树T R_Rotate(BSTree *p) 对以*p为根的平衡二叉排序树作右旋处理,处理之后p指向新的树根结点 即旋转处理之前的左子树的根结点 L_Rotate(BSTree *p) 对以*p为根的平衡二叉排序树作左旋处理,处理之后p指向新的树根结点, 即旋转处理之前的右子树的根结点 LeftBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序树作左平衡旋转处理, 本算法结束时,指针T指向新的根结点 RightBalance(BSTree *T) 对以指针T所指结点为根的平衡二叉排序树作右平衡旋转处理, 本算法结束时,指针T指向新的根结点 Insert_AVL(BSTree *T, TElemType e, int *taller) 若在平衡的二叉排序树T中不存在和e有相同的关键字的结点, 则插入一个数据元素为e的新结点,返回OK,否则返回ERROR. 若因插入而使二叉排序树失去平衡,则作平衡旋转处理 布尔变量taller反映T长高与否 InOrderTraverse(BSTree T) 递归中序遍历输出平衡二叉排序树 SearchBST(BSTree T, TElemType e, BSTree *f, BSTree *p) 在根指针T所指的平衡二叉排序树中递归的查找其元素值等于e的数据元素, 若查找成功,则指针p指向该数据元素结点,返回TRUE,否则指针p 指向查找路径上访问的最后一个结点返回FALSE,指针f指向T的双亲, 其初始调用值为NULL Delete_AVL(BSTree *T, TElemType e, int *shorter)平衡二叉排序树中删除元素值为e的结点,成功返回OK,失败返回ERROR PrintBSTree_GList(BSTree T) 以广义表形式打印出来 PrintBSTree_AoList(BSTree T, int length) 以凹入表形式打印,length初始值为0 Combine_Two_AVL(BSTree *T1, BSTree T2)两棵平衡二叉排序树 Split_AVL(BSTree T, BSTree *T1, BSTree *T2) 拆分两棵平衡二叉树 } (2)存储结构的定义: typedef struct BSTNode { TElemType data; int bf; //结点的平衡因子 struct BSTNode *lchild, *rchild;//左.右孩子指针 }BSTNode, *BSTree;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水之积也不厚,则其负大舟也无力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值