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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

1123. Is It a Complete AVL Tree (30)

發(fā)布時間:2025/3/15 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1123. Is It a Complete AVL Tree (30) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1123. Is It a Complete AVL Tree (30)

時間限制400 ms
內(nèi)存限制65536 kB
代碼長度限制16000 B
判題程序Standard作者CHEN, Yue

An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Figures 1-4 illustrate the rotation rules.

????

????

Now given a sequence of insertions, you are supposed to output the level-order traversal sequence of the resulting AVL tree, and to tell if it is a complete binary tree.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<= 20). Then N distinct integer keys are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, insert the keys one by one into an initially empty AVL tree. Then first print in a line the level-order traversal sequence of the resulting AVL tree. All the numbers in a line must be separated by a space, and there must be no extra space at the end of the line. Then in the next line, print "YES" if the tree is complete, or "NO" if not.

Sample Input 1:5 88 70 61 63 65 Sample Output 1:70 63 88 61 65 YES Sample Input 2:8 88 70 61 96 120 90 65 68 Sample Output 2:88 65 96 61 70 90 120 68 NO

題意:輸入n個數(shù)據(jù),要求創(chuàng)建avl平衡樹,再層序輸出并判斷是否是完全二叉樹

分析:我覺得層序輸出問題不大,主要在于avl的創(chuàng)建和判斷完全二叉樹

? avl的創(chuàng)建分為兩步 1.插入 2.平衡

? ? ? ? ? 插入比較好做,根據(jù)值的大小左右走,走到空的時候開始創(chuàng)建節(jié)點

? ? ? ? ? 插入節(jié)點可能會導(dǎo)致失衡,而平衡的方式根據(jù)插入節(jié)點與被破壞的節(jié)點的位置關(guān)系分為四種情況

? ? ? ? ?? 1.插入點是被破壞點左孩子的左孩子,如題目中Figure1,這時候需要左旋,即把88節(jié)點順時針旋轉(zhuǎn)成70節(jié)點的右孩子。(LL)

? ? ? ? ? ? ? ? 2.插入點是被破壞點右孩子的右孩子,如題目中Figure2,這時候需要右旋,即把88節(jié)點逆時針旋轉(zhuǎn)成96節(jié)點的左孩子(RR)

? ? ? ? ? ? ? ? 3.插入點是被破壞點右孩子的左孩子,如題目中Figure3,你會發(fā)現(xiàn)這個似乎有點不一樣,插入節(jié)點和被破壞的節(jié)點中間隔了兩個,這時候怎么旋轉(zhuǎn)呢?(RL)? ? RL是LL與RR之和,先對被破壞點的右孩子(96)進(jìn)行LL,在對被破壞點(70)進(jìn)行RR.

Figure的中間圖應(yīng)該是這樣的

可以看出旋轉(zhuǎn)的時候,88的子節(jié)點發(fā)生了變化,具體下面講

? ? ? ? ? ? ? ? ? 4.插入點是被破壞點左孩子的右孩子,如題目中Figure4(LR),先對61-65做RR旋轉(zhuǎn),在對70-70的左孩子(旋轉(zhuǎn)后為65) 做左旋

?再對LL做一個解釋,以Figure1 的88-70-61為例,此時的頭為88,我們希望旋轉(zhuǎn)后的頭的70,并且70的左為61,右為88。 我們假設(shè)此時的70節(jié)點有值為33的右孩子,那么88占了70的右子樹以后,33該往哪放呢????顯而易見,88的左子樹。 因為原先88的左孩子是70,旋轉(zhuǎn)以后左孩子就會空出來,那么就把88所占去的33放在空出來的這里。

示例代碼:

struct node* LL(struct node *root) {struct node *p = root->lchild;//p=70,root=88root->lchild = p->rchild;//88的左孩子=33p->rchild = root;//70的右孩子=88root->high = max(get_high(root->lchild), get_high(root->rchild)) + 1;p->high = max(get_high(p->lchild), root->high) + 1;//重新計算高度return p; }struct node *RL(struct node *root) {root->rchild = LL(root->rchild);return RR(root); }? ? ? ? ?RL,LR就是 RR ,LL 的組合。

? ? ? ? 接下來是完全二叉樹的判斷,
? ? ? ? 完全二叉樹怎么講呢,比起滿二叉樹的完整金字塔,完全二叉樹允許金字塔底部挖空,并且空之前必須全部填滿,空之后必須全部為空。“偷”了一張百度的圖片,圖1是滿二叉樹,圖2、3是完全二叉樹,圖4 、5就不是完全二叉樹。? ?所以,假設(shè)一顆完全二叉樹有n個頂點,如果第x個頂點有左子樹,并且x*2>n,那么我們可以判斷出它不是完全二叉樹。同理,如果第x個頂點有右子樹,并且x*2+1>n,那么我們可以判斷它不是完全二叉樹。



代碼:

#include<iostream> #include<queue> #include<algorithm> using namespace std; struct node {int data;int high;struct node *lchild, *rchild; }; int judge = 1, cnt = 0, n; void level_out(struct node root) {queue<struct node> q;q.push(root);while (q.size()) {if (q.front().lchild) q.push(*q.front().lchild);if (q.front().rchild) q.push(*q.front().rchild);if (q.front().lchild)if ((cnt + 1) * 2 > n) judge = 0;if (q.front().rchild)//判斷是否為 完全二叉樹if ((cnt + 1) * 2 + 1 > n) judge = 0;cnt == 0 ? cout << q.front().data : cout << " " << q.front().data;q.pop();cnt++;}cout << endl;judge == 1 ? cout << "YES" : cout << "NO"; } int get_high(struct node *root) {if (root) return max(get_high(root->lchild), get_high(root->rchild)) + 1;else return 0; } struct node* LL(struct node *root) {struct node *p = root->lchild;root->lchild = p->rchild;p->rchild = root;root->high = max(get_high(root->lchild), get_high(root->rchild)) + 1;p->high = max(get_high(p->lchild), root->high) + 1;return p; } struct node *RR(struct node *root) {struct node *p = root->rchild;root->rchild = p->lchild;p->lchild = root;root->high = max(get_high(root->lchild), get_high(root->rchild)) + 1;p->high = max(root->high, get_high(p->rchild)) + 1;return p; } struct node *RL(struct node *root) {root->rchild = LL(root->rchild);return RR(root); } struct node *LR(struct node *root) {root->lchild = RR(root->lchild);return LL(root); } struct node* insert(struct node* root, int data) {if (!root){root = new struct node();//使用默認(rèn)的構(gòu)造函數(shù)root->data = data;}else if (data < root->data){root->lchild = insert(root->lchild, data);if (get_high(root->lchild) - get_high(root->rchild) == 2) //失衡 if (data < root->lchild->data) root = LL(root);else root = LR(root);}else if (data >root->data){root->rchild = insert(root->rchild, data);if (get_high(root->rchild) - get_high(root->lchild) == 2)if (data > root->rchild->data) root = RR(root);else root = RL(root);}root->high = max(get_high(root->lchild), get_high(root->lchild)) + 1;return root; } int main() {int tmp;cin >> n;struct node *root = NULL;for (int i = 0; i<n; i++) {cin >> tmp;root = insert(root, tmp);}level_out(*root); }

轉(zhuǎn)載于:https://www.cnblogs.com/childwang/p/8280267.html

總結(jié)

以上是生活随笔為你收集整理的1123. Is It a Complete AVL Tree (30)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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