日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二十六、平衡二叉树

發布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二十六、平衡二叉树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二十六、平衡二叉樹

文章目錄

  • 二十六、平衡二叉樹
    • 題目描述
    • 解題思路
    • 上機代碼

題目描述

程序輸入一個字符串(只包含小寫字母),請按照字符的輸入順序建立平衡二叉排序樹,并分別輸出二叉樹的先序序列、中序序列和后序序列,最后輸出該二叉樹向左旋轉 90 度后的結構。

例如:向左旋轉 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

測試輸入期待的輸出時間限制內存限制額外進程
測試用例 1agxnzyimkPreorder: xigamknzy
Inorder: agikmnxyz
Postorder: agknmiyzx
Tree:
????z
????????y
x
????????????n
????????m
????????????k
i
????????g
????????????a
1秒64M0
測試用例 2asdfghjklPreorder: gdafjhlks
Inorder: adfghjkls
Postorder: afdhksljg
Tree:
????????????s
????????l
????????????k
????j
????????h
g
????????f
????d
????????a
1秒64M0

解題思路

教材第233—236頁詳細介紹了平衡二叉樹的定義和實現方式,第236—238頁給出了部分代碼實例。

平衡二叉樹又稱AVL樹,它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過1。將二叉樹上結點的平衡因子定義為該結點的左子樹深度減去右子樹的深度,平衡二叉樹上所有結點的平衡因子只能是-1、0或1。

平衡二叉樹的類型定義為:

typedef struct NODE {char data; //數據域 int bf; //平衡因子 struct NODE *lchild; //左孩子 struct NODE *rchild; //右孩子 }BSnode, *BSTree;

平衡化:

  • L平衡旋轉:將A的左孩子B向右上旋轉代替A成為根結點,將A結點向右下旋轉成為B的右子樹的根結點,而B的原右子樹作為A結點的左子樹
  • R平衡旋轉:將A的右孩子B向左上旋轉代替A成為根結點,將A結點向左下旋轉成為B的左子樹的根結點,而B的原左子樹作為A結點的右子樹
  • LR平衡旋轉:先將A結點的左孩子B的右子樹的根節點C向左上旋轉提升到B結點的位置,然后再把該C結點向右上旋轉提升到A結點的位置
  • RL平衡旋轉:先將A結點的右孩子B的左子樹的根節點C向右上旋轉提升到B結點的位置,然后再把該C結點向左上旋轉提升到A結點的位置

上機代碼

#include<cstdio> #include<cstdlib> #include<cstdlib>#define LH +1 //左高 #define EH 0 //等高 #define RH -1 //右高 typedef struct NODE {char data; //數據域 int bf; //平衡因子 struct NODE *lchild; //左孩子 struct NODE *rchild; //右孩子 }BSnode, *BSTree;void R_Rotate(BSTree *ptr)//右旋 {BSTree lc = (*ptr)->lchild; //lc指向的*ptr的左孩子的根結點 (*ptr)->lchild = lc->rchild; //lc的右子樹掛接為*ptr的左子樹 lc->rchild = *ptr;*ptr = lc; //ptr指向新的結點" } void L_Rotate(BSTree *ptr)//左旋 {BSTree rc = (*ptr)->rchild; //rc指向的*ptr的由孩子的根結點(*ptr)->rchild = rc->lchild; //rc的左子樹掛接為*ptr的右子樹rc->lchild = *ptr;*ptr = rc; //ptr指向新的結點 } void LeftBalance(BSTree *root)//左平衡旋轉處理 {BSTree lc;BSTree rd;lc = (*root)->lchild; //ls指向*root的左根結點//檢測*root的左子樹的平衡度,并作相應處理switch (lc->bf){case LH:{//新結點插入在*root的左孩子的左子樹上,要做單右旋處理(*root)->bf = lc->bf = EH;R_Rotate(root);break;}case RH:{//新結點插入在*root左孩子的右子樹上要做雙旋處理//rd指向*t的左孩子的右子樹根上rd = lc->rchild;switch (rd->bf){//修改*root及其左孩子的平衡因子case LH:{(*root)->bf = RH;lc->bf = EH;break;}case EH:{(*root)->bf = lc->bf = EH;break;}case RH:{(*root)->bf = EH;lc->bf = LH;break;}}rd->bf = EH;//對*root的左子樹左左旋平衡處理L_Rotate(&(*root)->lchild);//對*root做右旋平衡處理R_Rotate(root);}} } void RightBalance(BSTree *root)//右平衡旋轉處理 {BSTree lc;BSTree rd;lc = (*root)->rchild;switch (lc->bf){case RH:{(*root)->bf = lc->bf = EH;L_Rotate(root);break;}case LH:{rd = lc->lchild;switch (rd->bf){case LH:{(*root)->bf = EH;lc->bf = RH;break;}case EH:{(*root)->bf = lc->bf = EH;break;}case RH:{(*root)->bf = LH;lc->bf = EH;break;}}rd->bf = EH;R_Rotate(&(*root)->rchild);L_Rotate(root);}} }int InsertAVL(BSTree *root, char e, bool *taller) {if ((*root) == NULL){//該樹為一棵空樹,創建一個新節點作為根節點(*root) = (BSTree)malloc(sizeof(BSnode));(*root)->bf = EH;(*root)->data = e;(*root)->lchild = NULL;(*root)->rchild = NULL;*taller = true;}else if (e == (*root)->data)//關鍵字相同,則不再繼續插入{*taller = false;return 0;}else if (e < (*root)->data)//應該繼續在*root的左子樹進行搜索{if (!InsertAVL(&(*root)->lchild, e, taller))//未插入{return 0;}//已插入到*root的左子樹中并且左子樹長高if (*taller){//檢查*root的平衡度switch ((*root)->bf){//原本左子樹比右子樹高case LH:{//平衡因子為-1//左旋LeftBalance(root);*taller = false;break;}//原本左右樹一樣高,現在因為左子樹長高樹長高case EH:{//平衡因子為0(*root)->bf = LH;*taller = true;break;}//原本右子樹比左子樹高,現在等高case RH:{//平衡因子為1(*root)->bf = EH;*taller = false;break;}}}}else{//應繼續在*root的右子樹中進行搜索 if (!InsertAVL(&(*root)->rchild, e, taller))//未插入{return 0;}//已插入到*root的右子樹且右子樹長高if (*taller){//檢查*root的平衡度switch ((*root)->bf){case LH:{//原本左子樹比右子樹高,現在相等(*root)->bf = EH;*taller = false;break;}case EH:{//原來左右子樹登高,現在因為右子樹長高樹長高(*root)->bf = RH;*taller = true;break;}case RH:{//原本右子樹比左子樹高,需要做右旋平衡處理 RightBalance(root);*taller = false;break;}}}}return 1; } void printBIT(BSTree root, int x) {if (root != NULL){printBIT(root->rchild, x + 1);for (int i = 0; i < x; i++)printf(" ");printf("%c\n", root->data);printBIT(root->lchild, x + 1);} } void preorder(BSTree root) {if (root != NULL){printf("%c", root->data);preorder(root->lchild);preorder(root->rchild);} } void inorder(BSTree root)//二叉樹的中序遍歷 {if (root != NULL){inorder(root->lchild);printf("%c", root->data);inorder(root->rchild);} } void postorder(BSTree root) {if (root != NULL){postorder(root->lchild);postorder(root->rchild);printf("%c", root->data);} } int main() {char e;bool taller;//taller變量反應T長高與否BSTree root = NULL;while (e = getchar()){if (e == '\n')break;InsertAVL(&root, e, &taller);}//先序printf("Preorder: ");preorder(root);printf("\n");//中序printf("Inorder: ");inorder(root);printf("\n");//后序printf("Postorder: ");postorder(root);printf("\n");printf("Tree:\n");printBIT(root, 0);//system("pause");return 0; }

總結

以上是生活随笔為你收集整理的二十六、平衡二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。