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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

二十六、平衡二叉树

發(fā)布時(shí)間:2025/3/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二十六、平衡二叉树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

二十六、平衡二叉樹(shù)

文章目錄

  • 二十六、平衡二叉樹(shù)
    • 題目描述
    • 解題思路
    • 上機(jī)代碼

題目描述

程序輸入一個(gè)字符串(只包含小寫(xiě)字母),請(qǐng)按照字符的輸入順序建立平衡二叉排序樹(shù),并分別輸出二叉樹(shù)的先序序列、中序序列和后序序列,最后輸出該二叉樹(shù)向左旋轉(zhuǎn) 90 度后的結(jié)構(gòu)。

例如:向左旋轉(zhuǎn) 90 度后,以每層向里縮進(jìn) 4 個(gè)空格的方式輸出,輸出結(jié)果為:

?????i
??g
?????f
a
?????d
??c
?????b

輸入:agxnzyimk

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

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

解題思路

教材第233—236頁(yè)詳細(xì)介紹了平衡二叉樹(shù)的定義和實(shí)現(xiàn)方式,第236—238頁(yè)給出了部分代碼實(shí)例。

平衡二叉樹(shù)又稱(chēng)AVL樹(shù),它的左子樹(shù)和右子樹(shù)都是平衡二叉樹(shù),且左子樹(shù)和右子樹(shù)的深度之差的絕對(duì)值不超過(guò)1。將二叉樹(shù)上結(jié)點(diǎn)的平衡因子定義為該結(jié)點(diǎn)的左子樹(shù)深度減去右子樹(shù)的深度,平衡二叉樹(shù)上所有結(jié)點(diǎn)的平衡因子只能是-1、0或1。

平衡二叉樹(shù)的類(lèi)型定義為:

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

平衡化:

  • L平衡旋轉(zhuǎn):將A的左孩子B向右上旋轉(zhuǎn)代替A成為根結(jié)點(diǎn),將A結(jié)點(diǎn)向右下旋轉(zhuǎn)成為B的右子樹(shù)的根結(jié)點(diǎn),而B(niǎo)的原右子樹(shù)作為A結(jié)點(diǎn)的左子樹(shù)
  • R平衡旋轉(zhuǎn):將A的右孩子B向左上旋轉(zhuǎn)代替A成為根結(jié)點(diǎn),將A結(jié)點(diǎn)向左下旋轉(zhuǎn)成為B的左子樹(shù)的根結(jié)點(diǎn),而B(niǎo)的原左子樹(shù)作為A結(jié)點(diǎn)的右子樹(shù)
  • LR平衡旋轉(zhuǎn):先將A結(jié)點(diǎn)的左孩子B的右子樹(shù)的根節(jié)點(diǎn)C向左上旋轉(zhuǎn)提升到B結(jié)點(diǎn)的位置,然后再把該C結(jié)點(diǎn)向右上旋轉(zhuǎn)提升到A結(jié)點(diǎn)的位置
  • RL平衡旋轉(zhuǎn):先將A結(jié)點(diǎn)的右孩子B的左子樹(shù)的根節(jié)點(diǎn)C向右上旋轉(zhuǎn)提升到B結(jié)點(diǎn)的位置,然后再把該C結(jié)點(diǎn)向左上旋轉(zhuǎn)提升到A結(jié)點(diǎn)的位置

上機(jī)代碼

#include<cstdio> #include<cstdlib> #include<cstdlib>#define LH +1 //左高 #define EH 0 //等高 #define RH -1 //右高 typedef struct NODE {char data; //數(shù)據(jù)域 int bf; //平衡因子 struct NODE *lchild; //左孩子 struct NODE *rchild; //右孩子 }BSnode, *BSTree;void R_Rotate(BSTree *ptr)//右旋 {BSTree lc = (*ptr)->lchild; //lc指向的*ptr的左孩子的根結(jié)點(diǎn) (*ptr)->lchild = lc->rchild; //lc的右子樹(shù)掛接為*ptr的左子樹(shù) lc->rchild = *ptr;*ptr = lc; //ptr指向新的結(jié)點(diǎn)" } void L_Rotate(BSTree *ptr)//左旋 {BSTree rc = (*ptr)->rchild; //rc指向的*ptr的由孩子的根結(jié)點(diǎn)(*ptr)->rchild = rc->lchild; //rc的左子樹(shù)掛接為*ptr的右子樹(shù)rc->lchild = *ptr;*ptr = rc; //ptr指向新的結(jié)點(diǎn) } void LeftBalance(BSTree *root)//左平衡旋轉(zhuǎn)處理 {BSTree lc;BSTree rd;lc = (*root)->lchild; //ls指向*root的左根結(jié)點(diǎn)//檢測(cè)*root的左子樹(shù)的平衡度,并作相應(yīng)處理switch (lc->bf){case LH:{//新結(jié)點(diǎn)插入在*root的左孩子的左子樹(shù)上,要做單右旋處理(*root)->bf = lc->bf = EH;R_Rotate(root);break;}case RH:{//新結(jié)點(diǎn)插入在*root左孩子的右子樹(shù)上要做雙旋處理//rd指向*t的左孩子的右子樹(shù)根上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;//對(duì)*root的左子樹(shù)左左旋平衡處理L_Rotate(&(*root)->lchild);//對(duì)*root做右旋平衡處理R_Rotate(root);}} } void RightBalance(BSTree *root)//右平衡旋轉(zhuǎn)處理 {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){//該樹(shù)為一棵空樹(shù),創(chuàng)建一個(gè)新節(jié)點(diǎn)作為根節(jié)點(diǎn)(*root) = (BSTree)malloc(sizeof(BSnode));(*root)->bf = EH;(*root)->data = e;(*root)->lchild = NULL;(*root)->rchild = NULL;*taller = true;}else if (e == (*root)->data)//關(guān)鍵字相同,則不再繼續(xù)插入{*taller = false;return 0;}else if (e < (*root)->data)//應(yīng)該繼續(xù)在*root的左子樹(shù)進(jìn)行搜索{if (!InsertAVL(&(*root)->lchild, e, taller))//未插入{return 0;}//已插入到*root的左子樹(shù)中并且左子樹(shù)長(zhǎng)高if (*taller){//檢查*root的平衡度switch ((*root)->bf){//原本左子樹(shù)比右子樹(shù)高case LH:{//平衡因子為-1//左旋LeftBalance(root);*taller = false;break;}//原本左右樹(shù)一樣高,現(xiàn)在因?yàn)樽笞訕?shù)長(zhǎng)高樹(shù)長(zhǎng)高case EH:{//平衡因子為0(*root)->bf = LH;*taller = true;break;}//原本右子樹(shù)比左子樹(shù)高,現(xiàn)在等高case RH:{//平衡因子為1(*root)->bf = EH;*taller = false;break;}}}}else{//應(yīng)繼續(xù)在*root的右子樹(shù)中進(jìn)行搜索 if (!InsertAVL(&(*root)->rchild, e, taller))//未插入{return 0;}//已插入到*root的右子樹(shù)且右子樹(shù)長(zhǎng)高if (*taller){//檢查*root的平衡度switch ((*root)->bf){case LH:{//原本左子樹(shù)比右子樹(shù)高,現(xiàn)在相等(*root)->bf = EH;*taller = false;break;}case EH:{//原來(lái)左右子樹(shù)登高,現(xiàn)在因?yàn)橛易訕?shù)長(zhǎng)高樹(shù)長(zhǎng)高(*root)->bf = RH;*taller = true;break;}case RH:{//原本右子樹(shù)比左子樹(shù)高,需要做右旋平衡處理 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)//二叉樹(shù)的中序遍歷 {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變量反應(yīng)T長(zhǎng)高與否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; }

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。