資料結構實驗之查詢二:平衡二叉樹 (SDUT 3374)
阿新 • • 發佈:2018-12-16
#include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int data; int h; struct node *lc,*rc; //平衡二叉樹 需要一個 h 來記錄平衡因子 }; int max(int x ,int y) { if(x > y) return x; else return y; } int fin(struct node *root) // 返回這個結點的平衡因子,也就是左右子樹的差值 { if(root == NULL) return -1; else return root -> h; } struct node *LL(struct node *root) // 如果是左左型,也就是呈現 根 - 左子樹 p - 左子樹2 , 我們要把 根 變成 p 的右子樹 { struct node *p = root -> lc; root -> lc = p -> rc; p -> rc = root; p -> h = max(fin(p->lc),fin(p->rc)) + 1; // 更新這兩個點的平衡因子 root -> h = max(fin(root->lc),fin(root->rc)) + 1; return p; //別忘記返回 p } struct node *RR(struct node *root) // 同上相反 { struct node *p = root -> rc; root -> rc = p -> lc; p -> lc = root; p -> h = max(fin(p->lc),fin(p->rc)); root -> h = max(fin(root->lc),fin(root->rc)) + 1; return p; } struct node *LR(struct node *root) //LR型, 形如 根 - 左子樹 - 右子樹 { root -> lc = RR(root -> lc); return LL(root); } struct node *RL(struct node *root) { root -> rc = LL(root -> rc); return RR(root); } struct node *creat(struct node *root, int x) // 建樹的過程 { if(root == NULL) //如何到底層或者到可以放這個數的地方 { root = (struct node *)malloc(sizeof(struct node)); root -> data = x; root -> lc = root -> rc = NULL; // 左右孩子、h 初始化 root -> h = 0; } else if(root -> data > x) // 如果小的話,找左子樹, { root -> lc = creat(root -> lc, x); if(fin(root->lc) - fin(root->rc) > 1) // 如果找完之後,放進去之後,判斷時候不平衡了,如果不平衡,判斷是什麼樣子的型別,再旋轉 { if(root -> lc -> data > x) root = LL(root); // LL型,因為如果 root -> lc -> data > x,那麼 x 是放在了這個的左子樹 else root = LR(root); //相反,這樣子會放在右子樹 } } else if(root -> data < x) { root -> rc = creat(root -> rc, x); if(fin(root->rc) - fin(root->lc) >1) { if(root -> rc -> data < x) root = RR(root); else root = RL(root); } } root -> h = max(fin(root->lc),fin(root->rc)) + 1; // 沒插入一次新值,更新 root 的平衡因子 return root; } int main() { int n,m; scanf("%d",&n); struct node *root = NULL; for(int i = 0; i < n; i ++) { scanf("%d",&m); root = creat(root,m); } printf("%d\n",root->data); return 0; }