1. 程式人生 > >平衡二叉樹:左單旋&右單旋&左右單旋&右左單旋 遇到的問題&解決方法

平衡二叉樹:左單旋&右單旋&左右單旋&右左單旋 遇到的問題&解決方法

疑問為什麼要引入旋轉這一說法呢 因為在建立平衡二叉樹,插入二叉樹節點的時候,如果發現平衡因子不是-1,0,1的時候就會進行調整,而平衡因子是判斷一個二叉樹的每層是否平衡的資料 在程序調製的時候就會有左單旋,右單旋,左右旋轉,右左旋轉,通過這四種旋轉來使得不管插入多少資料都可以保持平衡二叉樹的特點 對著四種旋轉方式,我們以圖的方式來進行理解:(圖中的節點標記單詞用於理解原始碼)


生氣原始碼: #include<iostream> usingnamespacestd; template<classK,classV> structAVLTreeNode { AVLTreeNode
<K,V>* _left; AVLTreeNode<K,V>* _right; AVLTreeNode<K,V>* _parent; K_key;     V_value; int_bf;  //節點的平衡因子                 AVLTreeNode(constK&key,constV&value)                                 : _left(NULL)                                 , _right(NULL)                                 , _parent(
NULL)                                 , _key(key)                                 , _value(value)                                 , _bf(0)                 { } }; template<classK,classV> classAVLTree { typedefAVLTreeNode<K,V>Node; public:                 AVLTree()                                 :_root(
NULL)                 { } boolInsert(constK&key,constV&value)                 { if(_root ==NULL)                                 {                                                 _root =newNode(key,value); returntrue;                                 } //找新的節點要插入的位置 Node* cur = _root; Node* parent =NULL; while(cur)                                 { if(cur->_key <key)                                                 {                                                                 parent = cur;                                                                 cur = cur->_right;                                                 } elseif(cur->_key>key)                                                 {                                                                 parent = cur;                                                                 cur = cur->_left;                                                 } else                                                 { returnfalse;                                                 }                                 }                                 cur =newNode(key,value); if(parent->_key >key)                                 {                                                 parent->_left = cur;                                                 cur->_parent = parent;                                 } else                                 {                                                 parent->_right = cur;                                                 cur->_parent = parent;                                 } //更新平衡因子 //對於已經存在若干節點的二叉樹,在插入一個新結點的時候,會影響其父節點到根節點這一路的節點的平衡因子 //需要自下而上的開始調整其平衡因子,如果當前父節點的bf=1或-1,則把當前節點的父親給cur,把當前節點的父親的父親 //作為新的父親節點,然後對新的父節點的bf做調整,調整過後如果bf=1或-1,依然繼續向上調整,直到調整到根節點,因為 //父節點的父親為NULL,無法進入迴圈。當在調整的過程中遇到父節點的bf=2或-2的時候,則需要通過旋轉來調整二叉樹 //右單旋:cur->bf=-1  parent->bf=-2 //左單旋:cur->bf=1   parent->bf=2 //右左單旋:cur->bf=-1  parent->bf=2 //左右單旋:cur->bf=1   parent->bf=-2 while(parent)                                 { //如果新的節點在父節點的左邊,則平衡因子-- if(parent->_left == cur)                                                 {                                                                 parent->_bf--;                                                 } //如果新的節點在父節點的右邊,則平衡因子++ else                                                 {                                                                 parent->_bf++;                                                   } //平衡因子是0說明這個節點的高度是沒有變化的,沒有對父節點造成影響,所以不用再調整 if(parent->_bf == 0)                                                    { break;                                                 } //父節點平衡因子是1或-1說明該節點的平衡因子因為插入的節點而 //有了變化,而且會對父節點造成影響,所以繼續向上調整 elseif(parent->_bf == 1 || parent->_bf == -1)                                                 {                                                                 cur = parent;                                                                 parent = parent->_parent;                                                 } else//平衡因子為2或-2                                                 { if(cur->_bf == 1)                                                                 { //cur->bf=1,parent->bf=2  左單旋 if(parent->_bf == 2)                                                                                 {                                                                                                 RotateL(parent);                                                                                 } //cur->bf=1,parent->bf=-2  左右雙旋 else                                                                                 {                                                                                                 RotateLR(parent);                                                                                 }                                                                 } else//cur->bf=-1                                                                 { //cur->bf=-1,parent->bf=-2  右單旋 if(parent->_bf == -2)                                                                                 {                                                                                                 RotateR(parent);                                                                                 } //cur->bf=-1,parent->bf=2  右左單旋 else                                                                                 {                                                                                                 RotateRL(parent);                                                                                 }                                                                 } break;                                                 }                                 } returntrue;                 } voidInOrder()                 {                                 _InOrder(_root);                                 cout << endl;                 } boolIsBlance()                 { return_IsBlance(_root);                 } protected: //左單旋 voidRotateL(Node*parent)                 { Node* subR =parent->_right; Node* subRL = subR->_left; parent->_right = subRL; if(subRL)                                                 subR->_parent =parent;                                 subR->_left =parent; Node* ppNode =parent->_parent; parent->_parent = subR; if(ppNode ==NULL)                                 {                                                 _root = subR;                                                 subR->_parent =NULL;                                 } else                                 { if(ppNode->_left ==parent)                                                 {                                                                 ppNode->_left = subR;                                                                 subR->_parent = ppNode;                                                 } else                                                 {                                                                 ppNode->_right = subR;                                                                 subR->_parent = ppNode;                                                 }                                               } parent->_bf = subR->_bf = 0;                 } //右單旋 voidRotateR(Node*parent)                 { Node* subL =parent->_left; Node* subLR = subL->_right; parent->_left= subLR; if(subLR)                                                 subLR->_parent =parent;                                 subL->_right =parent; Node* ppNode =parent->_parent; parent->_parent = subL; if(ppNode ==NULL)                                 {                                                 _root = subL;                                                 subL->_parent =NULL;                                 } else                                 { if(ppNode->_left ==parent)                                                 {                                                                 ppNode->_left = subL;                                                                 subL->_parent = ppNode;                                                 } else                                                 {                                                                 ppNode->_right = subL;                                                                 subL->_parent = ppNode;                                                 }                                                               } parent->_bf = subL->_bf = 0;                 } voidRotateLR(Node*parent

相關推薦

平衡&&左右& 遇到的問題&解決方法

為什麼要引入旋轉這一說法呢? 因為在建立平衡二叉樹,插入二叉樹節點的時候,如果發現平衡因子不是-1,0,1的時候就會進行調整,而平衡因子是判斷一個二叉樹的每層是否平衡的資料 在程序調製的時候就會有左

手動編寫AVL(平衡),實現了基本的add、get 、remove、 toString、 contains等方法

平衡二叉樹:是指一棵空樹或者是任意節點的左右孩子的高度相差絕對值小於等於1 package com.hcc.DStructure; import java.util.ArrayList; import java.util.concurrent.ArrayBlockingQ

PAT 1123—— Is It a Complete AVL Tree(平衡)【各種

#include <cstdio> #include <algorithm> #include <vector> #include <iostream> #include <queue> using namespace std;

平衡(AVL)一圖一步驟程式碼實現左右平衡操作

/** * @version 建立時間: 2017-11-21 下午10:10:27 * 類說明:AVL樹 */ public class AVLTree<E extends Compar

面試題平衡

depth 二叉樹 面試 true 思路 nod balance urn oot 題目描述:輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。 思路:利用上一題求二叉樹的深度 public class Solution { public boolean IsBalan

劍指offer第55.5平衡

題目描述 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。 class Solution: def IsBalanced_Solution(self, pRoot): # write code here if not pRoot:

演算法題(三十判斷是否是平衡

7. 判斷是否是BST 題目描述 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。 分析 可以用遞迴的方法,從下向上遍歷各個結點(後序遍歷),如果結點是滿足BST的條件則返回該結點的高度,如果不滿足則直接停止遍歷並返回false。 程式碼 public cl

劍指offer輸入一棵,判斷該是否是平衡

輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。 //後續遍歷二叉樹,遍歷過程中求子樹高度,判斷是否平衡 class Solution { public: bool IsBalanced(TreeNode *root, int & dep){

劍指offer-39平衡

題目描述 輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。 思路 首先,什麼是平衡二叉樹?如果二叉樹中任意結點的左右子樹深度相差不超過1,那麼它就是平衡二叉樹。 最直接的做法,遍歷每個結點,藉助一個獲取樹深度的遞迴函式,根據該結點的左右子樹高度差判斷是否平衡,然後遞迴地對左右子樹進

資料結構實驗之查詢平衡 (SDUT 3374)

#include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int data; int h; struct node *lc,*rc; //平衡二

面試題55(平衡

一、題目 輸入一棵二叉樹的根結點,判斷該樹是不是平衡二叉樹。如果某二叉樹中任意結點的左右子樹的深度相差不超過1,那麼它就是一棵平衡二叉樹。 二、關鍵 三、解釋 四、程式碼 #include <cstdio> #include "..\Utilities\

AVL平衡 平衡因子 旋轉LL 旋轉RR LR RL

  前言   今天要介紹幾種高階資料結構AVL樹,介紹之前AVL,會先說明平衡二叉樹,並將樹的學習路線進行總結,並介紹維持平衡的方法:右旋轉、左旋轉。   一、樹學習路線   1、路線總結   總結了一下樹的學習路線,如下圖:      2、說明   上面這個圖要從上往下進行一步一步學習;首先,

#資料結構與演算法學習筆記#劍指Offer35是否平衡/AVL + 測試用例(Java、C/C++)

2018.11.3 前幾天有用遞迴實現了二叉樹的深度#資料結構與演算法學習筆記#劍指Offer36:二叉樹的深度(Java),因此可以對每個結點先序遍歷進行一次平衡驗證,只要確定每個結點都是平衡的

簡直off 平衡

文章目錄 前言 題目 思路 暴力揭發 優化,從下往上的 前言 最近有道雲筆記老是沒響應,會員也這樣,所以把演算法的筆記公開到這個csdn,也算是公開的鞭策。 題目常練習起點位置: https://www.nowcod

平衡插入—旋轉雙旋轉問題

平衡二叉樹插入一個節點時,往往會造成平衡二叉樹的不平衡,這時就要我們編寫程式恢復平衡二叉樹的平衡。下圖就因為插入了1,造成了樹的不平衡。   總的來說,消除不平衡有兩種方法,一個是單旋轉,另一個是雙旋轉,雙旋轉就是兩次單旋轉的疊加。我記得大二資料結構的教材是分了LR LL

平衡各種演算法詳解一紅黑

平衡二叉樹(Balanced Binary Tree)具有以下性質:它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。平衡二叉樹的常用演算法有紅黑樹、AVL、Treap、伸展樹、SBT等。最小二叉平衡樹的節點的公式如下 F(n)=

平衡——AVL的旋轉操作Java語言實現

1 前言2 平衡二叉樹——AVL樹的旋轉操作2.1 AVL樹的特點 AVL樹本質上還是一棵二叉搜尋樹,它的特點是:1.本身首先是一棵二叉搜尋樹。2.帶有平衡條件:每個結點的左右子樹的高度之差的絕對值(平衡因子)最多為1。也就是說,AVL樹,本質上是帶了平衡功能的二叉查詢樹(二

劍指Offer38平衡

思路: 判斷是否是平衡二叉樹,即判斷任何一個節點的左子樹和右子樹的高度差的絕對值小於等於1。最直接的做法,遍歷每個結點,藉助一個獲取樹深度的遞迴函式,根據該結點的左右子樹高度差判斷是否平衡,然後遞迴地對左右子樹進行判斷。 # class TreeNode: # def __init_

劍指offer程式設計題(JAVA實現)——第39題平衡

github https://github.com/JasonZhangCauc/JZOffer 劍指offer程式設計題(JAVA實現)——第39題:平衡二叉樹 題目描述

劍指Offer系列-面試題39-2判斷一棵是否為平衡

題目:判斷一棵樹是否為平衡二叉樹 思路:根據上一題的二叉樹的深度,在遞迴過程中加上識別符號,遞迴到當前節點,判斷當前子樹是不是一個平衡二叉樹,如果不是,就把識別符號置為false,返回識別符號即可。