文章目錄
- 1.AVL樹的提出
- 平衡因子
- 2.AVL樹的節點定義
- 3.AVL樹類
- ①AVL樹插入節點(插入成功回傳一個pair值)
- 更新平衡因子
- 當平衡因子變為2或-2時,四種旋轉調整AVL樹
- 右單旋(新節點插入較高左子樹的左側)
- _右單旋代碼
- 左單旋(新節點插入較高右子樹的右側)
- _左單旋代碼
- 左右雙旋(新節點插入較高左子樹的右側)
- _左右雙旋代碼
- 右左雙旋(新節點插入較高右子樹的左側)
- _右左雙旋代碼
- AVL樹插入C++實作
- ②判斷是否是AVL樹代碼
- ③AVL樹通過鍵值C++查找代碼
- ④AVL樹的C解構式
- ⑤利用插入函式的回傳值多載[]實作AVL樹的修改
- 4.AVL樹插入,修改C++代碼
- 測驗代碼
- 運行結果
- 5.代碼Github/Gitree代碼位置
1.AVL樹的提出
二叉搜索樹雖然可以提高搜索效率,但如果資料接近有序的話搜索二叉樹的效率退化為鏈表了,為了解決這個問題,提出了AVL樹,
向平衡二叉樹中插入新節點,保證每個節點的高度差的絕對值小于等于1,降低樹的高度,提高搜索效率,這種樹稱為AVL樹
平衡因子
每個節點的平衡因子=這個節點的右子樹高度-這個節點的左子樹高度,
注意:平衡因子不是AVL樹必須的,這里實作AVL樹時節點選擇了添加了平衡因子
2.AVL樹的節點定義
template<class Key,class Val>
struct AVLNode
{
AVLNode<Key, Val>* _Left;
AVLNode<Key, Val>* _Right;
AVLNode<Key, Val>* _Parent;//記錄節點的父節點,方便旋轉
int _bf;//平衡因子
pair<Key, Val> _KV;
AVLNode(const pair<Key, Value>& kv) :_Left(nullptr), _Right(nullptr)
, _Parent(nullptr), _bf(0), _KV(kv)
{}
};
3.AVL樹類
template<class Key, class Val>
class AVLTree
{
public:
typedef AVLNode<Key, Val> Node;
AVLTree() :_root(nullptr) {}
pair<Node*,bool> Insert(const pair<Key, Val>& kv);//向AVL樹中插入節點,插入成功回傳這個位置的指標和true,失敗回傳這個位置的指標和false
Node* Find(const Key& key);//通過鍵值來查找對應鍵值節點,成功回傳對應節點的指標,失敗回傳空
void PrintTree()//中序列印AVL樹
{
_PrintTree(_root);
}
private:
Node* _root;
void _PrintTree(Node* root)
{
if (root == nullptr)
return;
_PrintTree(root->_Left);
cout << root->_KV.first << "->" << root->_KV.second << endl;
_PrintTree(root->_Right);
}
/*
四種旋轉,看下文分析,下面的四種旋轉函式為類的成員函式
*/
};
①AVL樹插入節點(插入成功回傳一個pair值)
向AVL樹中插入節點是否旋轉取決于樹中的平衡因子,當平衡因子的絕對值大于1證明需要調整AVL樹的高度,
更新平衡因子
插入節點后,這個節點的父節點到根節點的路徑上的所有節點的平衡因子可能要改變,新插入的節點平衡因子為0,這在建構式中就可以保證,
平衡因子=右樹-左樹,
所以插入節點在父節點左邊,父節點的平衡因子-1,反之父節點的平衡因子+1;
如果父節點經過調整后,平衡因子為1或者-1,說明原來父節點的因子為0,這次插入改變了父節點原來的高度,還要繼續向上調整平衡因子,
如果父節點經過調整后,平衡因子變為0,說明原來父節點的因子為1或-1,這次插入沒有改變父節點的高度,不需要繼續向上調整平衡因子,
如果父節點經過調整后,平衡因子變為2或-2,說明此時不滿足AVL樹特性,要通過旋轉來調整高度,
當平衡因子變為2或-2時,四種旋轉調整AVL樹
旋轉的基本準則:在旋轉后這棵樹還是搜索樹,只是讓其盡可能的保持平衡
這里將二叉樹抽象為高度為h的矩形來概括情況
右單旋(新節點插入較高左子樹的左側)

右單旋的情況為插入節點的父節點的平衡因子為-1,且這個節點父節點的父節點平衡因子為-2,
如上圖表現為右高左低,將a節點連接到b右節點,將原來b右子樹連接到a左子樹上,
注意還要調節對應節點的父指標,讓a的父指標指向b,Rh的父指標指向a(如果Rh存在的話,不存在(h=0)不需要處理),b的父指標指向空
旋轉后如上圖,修改平衡因子的值為0,
調整根節點:上圖因為旋轉的是根節點,這時只要把b作為根節點即可,
當旋轉的是子樹時,原來的a的父節點要被保存下來,在旋轉完后b的父節點要指向這個節點,
只要發生旋轉一定是平衡因子從1/-1到2/-2,旋轉完后平衡因子變為0,相當于從1/-1到0,子樹的高度沒有發生變化,所以上面的平衡因子不變,不需要再向上調整了
_右單旋代碼
函式要傳入平衡因子為-2的節點指標,如上圖要傳入節點a的指標,
void _Single_Right(Node* parent)//根據圖把對應關系連接起來
{
//記錄要移動的節點
Node* SubL = parent->_Left;
Node* SubLR = SubL->_Right;
//連接
parent->_Left = SubLR;
if (SubL->_Right != nullptr)//修改父指標
{
SubLR->_Parent = parent;
}
//連接
SubL->_Right = parent;
Node* GradParent = parent->_Parent;//記錄這個節點的父節點,為了修改根節點
parent->_Parent = SubL;//修改父指標
//修改平衡因子為0
parent->_bf = 0; SubL->_bf = 0;
//調整根節點
if (parent == _root)//要旋轉的節點為根節點
{
_root = SubL;
SubL->_Parent = GradParent;
}
else//要旋轉的節點是子樹,修改GradParent指標
{
if (GradParent->_Left == parent)
{
GradParent->_Left = SubL;
}
else
{
GradParent->_Right = SubL;
}
SubL->_Parent = GradParent;
}
}
左單旋(新節點插入較高右子樹的右側)

左單旋與右單旋情況類似:觀察上圖:
左單旋的情況為插入節點的父節點的平衡因子為1,且這個節點父節點的父節點平衡因子為2,
將bL連接到a的右樹上,a再連接到b的左樹上,調整平衡因子a,b平衡因子都變為0,調整a,b節點父指標,調整樹的根節點,處理子樹的情況,細節和右單旋類似,
_左單旋代碼
void _Single_Left(Node* parent)//左旋轉
{
//記錄要移動的節點
Node* SubR = parent->_Right;
Node* SubRL = SubR->_Left;
//連接
parent->_Right = SubRL;
if (SubRL != nullptr)
{
SubRL->_Parent = parent;
}
SubR->_Left = parent;
Node* GradParent = parent->_Parent;//記錄這個節點的父節點,為了修改根節點
parent->_Parent = SubR;
//修改平衡因子
parent->_bf = 0; SubR->_bf = 0;
//調整根節點
if (parent == _root)
{
_root = SubR;
SubR->_Parent = GradParent;
}
else //要旋轉的節點是子樹,修改GradParent指標
{
if (GradParent->_Left == parent)//旋轉的是左子樹,連接到左邊
{
GradParent->_Left = SubR;
}
else
{
GradParent->_Right = SubR;//反之
}
SubR->_Parent = GradParent;
}
}
左右雙旋(新節點插入較高左子樹的右側)

由上圖可以看到a節點的平衡因子為-2,b節點的平衡因子為1時要進行左右雙旋,
特點為:b節點進行左旋,a節點進行右旋,
因為上面已經寫過左旋右旋的代碼,直接復用即可,
但是這時要分析平衡因子的變化
觀察上圖,相當于把c節點拆開c做根節點,c的左子樹給b右樹,c的右子樹給a的左樹,c的左子樹連接b,c的右子樹連接a,從而達到降低樹的高度的目的,
根據上面的分析可知c在旋轉后平衡因子一定為0.
如果新節點插入的位置在c的左子樹上,經過旋轉會到b的右子樹上,b的平衡因子為0,a的平衡因子為1.
如果新節點插入的位置在c的右子樹上,經過旋轉會到a的左子樹上,b的平衡因子為-1,a的平衡因子為0(如上圖).
特殊情況:當b節點沒有子樹時,即這顆樹只有cba這三個節點,此時a,b,c這三個節點的平衡因子都為0,
上面的這三種情況都是以c節點的平衡因子來判斷的,如果c的平衡因子變為1,說明其插入到了c節點的右子樹上,對應第二種情況,如果c的平衡因子變為-1,說明其插入到了c節點的左子樹上,對應第一種情況,如果c作為插入的節點,此時對應的是特殊情況,

先記錄旋轉改變的這三個節點指標,通過判斷SubLR中平衡因子來判斷是那種情況,與上面的對應處理即可,
_左右雙旋代碼
void _Single_LeftRight(Node* parent)//左右雙旋
{
//記錄節點的位置
Node* SubL = parent->_Left;
Node* SubLR = SubL->_Right;
//先左旋,再右旋
_Single_Left(parent->_Left);
_Single_Right(parent);
//根據SubRL判斷是什么型別,修改平衡因子
if (SubLR->_bf == 1)//插入到右子樹上
{
SubLR->_bf = 0;
SubL->_bf = -1;
parent->_bf = 0;
}
else if (SubLR->_bf == -1)//插入到左子樹上
{
parent->_bf = 1;
SubL->_bf = 0;
SubLR->_bf = 0;
}
else if (SubLR->_bf == 0)//特殊情況,插入后只有三個節點,三個節點的平衡因子都為0,
{
parent->_bf = 0;
SubL->_bf = 0;
SubLR->_bf = 0;
}
else//發生錯誤
{
assert(false);
}
}
右左雙旋(新節點插入較高右子樹的左側)

由上圖可以看到a節點的平衡因子為2,b節點的平衡因子為-1時要進行右左雙旋,
特點為:b節點進行右旋,a節點進行左旋,
具體細節看上圖,這里不在贅述
_右左雙旋代碼
void _Single_RightLeft(Node* parent)//右左雙旋
{
//記錄節點的位置
Node* SubR = parent->_Right;
Node* SubRL = SubR->_Left;
//先右旋,再左旋
_Single_Right(parent->_Right);
_Single_Left(parent);
//根據SubRL判斷是什么型別,修改平衡因子
if (SubRL->_bf == 1)//插入到右子樹上
{
SubRL->_bf = 0;
SubR->_bf = 0;
parent->_bf = -1;
}
else if (SubRL->_bf == -1)//插入到左子樹上
{
parent->_bf = 0;
SubRL->_bf = 0;
SubR->_bf = 1;
}
else if (SubRL->_bf == 0)//特殊情況,插入后只有三個節點,三個節點的平衡因子都為0,
{
parent->_bf = 0;
SubR->_bf = 0;
SubRL->_bf = 0;
}
else//發生錯誤
{
assert(false);
}
}
AVL樹插入C++實作
pair<Node*,bool> Insert(const pair<Key, Val>& kv)//向AVL樹中插入節點,插入成功回傳這個位置的指標和true,失敗回傳這個位置的指標和false
{
//根節點為空
if (_root == nullptr)
{
_root = new Node(kv);
return make_pair(_root, true);
}
//普通平衡二叉樹的插入(不允許鍵值冗余)
Node* parent = nullptr; Node* cur = _root;
while (cur != nullptr)
{
if (kv.first > cur->_KV.first)
{
parent = cur;
cur = cur->_Right;
}
else if (kv.first < cur->_KV.first)
{
parent = cur;
cur = cur->_Left;
}
else//找到重復鍵值退出回圈
{
return make_pair(cur, false);
}
}
//cur==nullptr
cur = new Node(kv);
Node* NewCur = cur;//保存新插入的節點,來回傳
if (parent->_KV.first > kv.first)
{
cur->_Parent = parent;//鏈接上一個節點
parent->_Left = cur;
}
else
{
cur->_Parent = parent;
parent->_Right = cur;
}
/*------------------------------------------------ */
//更新平衡因子(右-左)
while (parent != nullptr)
{
//判斷插入位置
if (parent->_Left == cur)
{
parent->_bf--;
}
else
{
parent->_bf++;
}
if (parent->_bf == 0)
{
break;//說明插入后仍然滿足AVL樹,不需要調整了,插入結束,
}
else if (parent->_bf == 1 || parent->_bf == -1)//高度改變,繼續向上調整
{
cur = parent;
parent = parent->_Parent;//繼續向上調整
}
else if (parent->_bf == 2 || parent->_bf == -2)//不滿足AVL樹特征,需要調整樹結構
{
//旋轉,對應四種不同的旋轉,看節點的平衡因子
if (parent->_bf == -2)
{
if (cur->_bf == -1)//右單旋
{
_Single_Right(parent);
}
else if (cur->_bf == 1)//左右雙旋
{
_Single_LeftRight(parent);
}
}
else//parent->_bf==2
{
if (cur->_bf == 1)//左單旋
{
_Single_Left(parent);
}
else if (cur->_bf == -1)//右左雙旋
{
_Single_RightLeft(parent);
}
}
break;
}
else//發生錯誤
{
assert(false);
}
}
return make_pair(NewCur, true);
}
②判斷是否是AVL樹代碼
思路:通過計算每個節點的左子樹和右子樹的差值的絕對值<1,并且這個差值和這個節點的平衡因子相同
二叉樹節點高度=這個節點左樹高度與這個節點右樹高度的最大值+1,
先檢查這個節點是不是符合AVL樹,再遞回檢查其他節點
//私有:
bool _IsAVLTree(Node* _root)
{
if (_root == nullptr)
return true;
int LeftHeight = _Height(_root->_Left);
int RightHeight = _Height(_root->_Right);
if (RightHeight - LeftHeight != _root->_bf)//發生錯誤
{
cout << "平衡因子錯誤" << endl;
return false;
}
return abs(LeftHeight - RightHeight) < 2//檢查左右子樹的高度再遞回檢查左子樹和右子樹
&& _IsAVLTree(_root->_Left) && _IsAVLTree(_root->_Right);
}
int _Height(Node* root)
{
if (root == nullptr)
return 0;
int LeftTreeHeight = _Height(root->_Left);
int RightTreeHeight = _Height(root->_Right);
return max(LeftTreeHeight, RightTreeHeight) + 1;
}
//共有
template<class Key, class Val>
bool AVLTree<Key, Val>::IsAVLTree()
{
return _IsAVLTree(_root);
}
③AVL樹通過鍵值C++查找代碼
與搜索二叉樹查找類似,遍歷樹即可
Node* Find(const Key& key)//通過鍵值來查找對應鍵值節點,成功回傳對應節點的指標,失敗回傳空
{
Node* cur = _root;
while (cur!=nullptr)
{
if (cur->_KV.first < key)
{
cur = cur->_Right;
}
else if (cur->_KV.first > key)
{
cur = cur->_Left;
}
else
{
return cur;
}
}
return nullptr;
}
④AVL樹的C解構式
這棵樹節點是由我們動態開辟的,為了防止記憶體泄漏,要手動寫解構式
思路:先遞回銷毀左子樹,再遞回銷毀右子樹,最后銷毀節點,后序遍歷
//私有
void _Destory(Node* root)
{
if (root == nullptr)
return;
_Destory(root->_Left);
_Destory(root->_Right);
delete root;
}
~AVLTree()
{
_Destory(_root);
}
⑤利用插入函式的回傳值多載[]實作AVL樹的修改
具體思路見博客:
利用插入函式回傳值多載思路
這里直接寫C++代碼
Val& operator[](const Key& key)
{
pair<Node*, bool>ret = Insert(make_pair(key, Val()));//利用插入函式的回傳值
return ret.first->_KV.second;
}
4.AVL樹插入,修改C++代碼
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
template<class Key,class Val>
struct AVLNode
{
AVLNode<Key, Val>* _Left;
AVLNode<Key, Val>* _Right;
AVLNode<Key, Val>* _Parent;
int _bf;//平衡因子
pair<Key, Val> _KV;
AVLNode(const pair<Key, Val>& kv) :_Left(nullptr), _Right(nullptr)
, _Parent(nullptr), _bf(0), _KV(kv)
{}
};
template<class Key, class Val>
class AVLTree
{
public:
typedef AVLNode<Key, Val> Node;
AVLTree() :_root(nullptr) {}
~AVLTree()
{
_Destory(_root);
}
//[]運算子多載
Val& operator[](const Key& key)
{
pair<Node*, bool>ret = Insert(make_pair(key, Val()));//利用插入函式的回傳值
return ret.first->_KV.second;
}
pair<Node*,bool> Insert(const pair<Key, Val>& kv)//向AVL樹中插入節點,插入成功回傳這個位置的指標和true,失敗回傳這個位置的指標和false
{
//根節點為空
if (_root == nullptr)
{
_root = new Node(kv);
return make_pair(_root, true);
}
//普通平衡二叉樹的插入(不允許鍵值冗余)
Node* parent = nullptr; Node* cur = _root;
while (cur != nullptr)
{
if (kv.first > cur->_KV.first)
{
parent = cur;
cur = cur->_Right;
}
else if (kv.first < cur->_KV.first)
{
parent = cur;
cur = cur->_Left;
}
else//找到重復鍵值退出回圈
{
return make_pair(cur, false);
}
}
//cur==nullptr
cur = new Node(kv);
Node* NewCur = cur;//保存新插入的節點,來回傳
if (parent->_KV.first > kv.first)
{
cur->_Parent = parent;//鏈接上一個節點
parent->_Left = cur;
}
else
{
cur->_Parent = parent;
parent->_Right = cur;
}
/*------------------------------------------------ */
//更新平衡因子(右-左)
while (parent != nullptr)
{
//判斷插入位置
if (parent->_Left == cur)
{
parent->_bf--;
}
else
{
parent->_bf++;
}
if (parent->_bf == 0)
{
break;//說明插入后仍然滿足AVL樹,不需要調整了,插入結束,
}
else if (parent->_bf == 1 || parent->_bf == -1)//高度改變,繼續向上調整
{
cur = parent;
parent = parent->_Parent;//繼續向上調整
}
else if (parent->_bf == 2 || parent->_bf == -2)//不滿足AVL樹特征,需要調整樹結構
{
//旋轉,對應四種不同的旋轉,看節點的平衡因子
if (parent->_bf == -2)
{
if (cur->_bf == -1)//右單旋
{
_Single_Right(parent);
}
else if (cur->_bf == 1)//左右雙旋
{
_Single_LeftRight(parent);
}
}
else//parent->_bf==2
{
if (cur->_bf == 1)//左單旋
{
_Single_Left(parent);
}
else if (cur->_bf == -1)//右左雙旋
{
_Single_RightLeft(parent);
}
}
break;
}
else//發生錯誤
{
assert(false);
}
}
return make_pair(NewCur, true);
}
Node* Find(const Key& key)//通過鍵值來查找對應鍵值節點,成功回傳對應節點的指標,失敗回傳空
{
Node* cur = _root;
while (cur!=nullptr)
{
if (cur->_KV.first < key)
{
cur = cur->_Right;
}
else if (cur->_KV.first > key)
{
cur = cur->_Left;
}
else
{
return cur;
}
}
return nullptr;
}
void PrintTree()//中序列印AVL樹
{
_PrintTree(_root);
}
bool IsAVLTree()//檢查是否是AVL樹
{
return _IsAVLTree(_root);
}
private:
Node* _root;
void _Destory(Node* root)
{
if (root == nullptr)
return;
_Destory(root->_Left);
_Destory(root->_Right);
delete root;
}
bool _IsAVLTree(Node* _root)
{
if (_root == nullptr)
return true;
int LeftHeight = _Height(_root->_Left);
int RightHeight = _Height(_root->_Right);
if (RightHeight - LeftHeight != _root->_bf)//發生錯誤
{
cout << "平衡因子錯誤" << endl;
return false;
}
bool tmp = abs(LeftHeight - RightHeight) < 2;
bool tmp2 = _IsAVLTree(_root->_Left);
bool tmp3 = _IsAVLTree(_root->_Right);
/*return abs(LeftHeight - RightHeight) < 2
&& _IsAVLTree(_root->_Left) && _IsAVLTree(_root->_Right);*/
}
int _Height(Node* root)
{
if (root == nullptr)
return 0;
int LeftTreeHeight = _Height(root->_Left);
int RightTreeHeight = _Height(root->_Right);
return max(LeftTreeHeight, RightTreeHeight) + 1;
}
void _PrintTree(Node* root)
{
if (root == nullptr)
return;
_PrintTree(root->_Left);
cout << root->_KV.first << "->" << root->_KV.second << endl;
_PrintTree(root->_Right);
}
void _Single_Right(Node* parent)//右單旋根據圖把對應關系連接起來
{
//記錄要移動的節點
Node* SubL = parent->_Left;
Node* SubLR = SubL->_Right;
//連接
parent->_Left = SubLR;
if (SubL->_Right != nullptr)//修改父指標
{
SubLR->_Parent = parent;
}
//連接
SubL->_Right = parent;
Node* GradParent = parent->_Parent;//記錄這個節點的父節點,為了修改根節點
parent->_Parent = SubL;//修改父指標
//修改平衡因子為0
parent->_bf = 0; SubL->_bf = 0;
//調整根節點
if (parent == _root)//要旋轉的節點為根節點
{
_root = SubL;
SubL->_Parent = GradParent;
}
else//要旋轉的節點是子樹,修改GradParent指標
{
if (GradParent->_Left == parent)
{
GradParent->_Left = SubL;
}
else
{
GradParent->_Right = SubL;
}
SubL->_Parent = GradParent;
}
}
void _Single_Left(Node* parent)//左旋轉
{
//記錄要移動的節點
Node* SubR = parent->_Right;
Node* SubRL = SubR->_Left;
//連接
parent->_Right = SubRL;
if (SubRL != nullptr)
{
SubRL->_Parent = parent;
}
SubR->_Left = parent;
Node* GradParent = parent->_Parent;//記錄這個節點的父節點,為了修改根節點
parent->_Parent = SubR;
//修改平衡因子
parent->_bf = 0; SubR->_bf = 0;
//調整根節點
if (parent == _root)
{
_root = SubR;
SubR->_Parent = GradParent;
}
else //要旋轉的節點是子樹,修改GradParent指標
{
if (GradParent->_Left == parent)//旋轉的是左子樹,連接到左邊
{
GradParent->_Left = SubR;
}
else
{
GradParent->_Right = SubR;//反之
}
SubR->_Parent = GradParent;
}
}
void _Single_LeftRight(Node* parent)//左右雙旋
{
//記錄節點的位置
Node* SubL = parent->_Left;
Node* SubLR = SubL->_Right;
//先左旋,再右旋
_Single_Left(parent->_Left);
_Single_Right(parent);
//根據SubRL判斷是什么型別,修改平衡因子
if (SubLR->_bf == 1)//插入到右子樹上
{
SubLR->_bf = 0;
SubL->_bf = -1;
parent->_bf = 0;
}
else if (SubLR->_bf == -1)//插入到左子樹上
{
parent->_bf = 1;
SubL->_bf = 0;
SubLR->_bf = 0;
}
else if (SubLR->_bf == 0)//特殊情況,插入后只有三個節點,三個節點的平衡因子都為0,
{
parent->_bf = 0;
SubL->_bf = 0;
SubLR->_bf = 0;
}
else//發生錯誤
{
assert(false);
}
}
void _Single_RightLeft(Node* parent)//右左雙旋
{
//記錄節點的位置
Node* SubR = parent->_Right;
Node* SubRL = SubR->_Left;
//先右旋,再左旋
_Single_Right(parent->_Right);
_Single_Left(parent);
//根據SubRL判斷是什么型別,修改平衡因子
if (SubRL->_bf == 1)//插入到右子樹上
{
SubRL->_bf = 0;
SubR->_bf = 0;
parent->_bf = -1;
}
else if (SubRL->_bf == -1)//插入到左子樹上
{
parent->_bf = 0;
SubRL->_bf = 0;
SubR->_bf = 1;
}
else if (SubRL->_bf == 0)//特殊情況,插入后只有三個節點,三個節點的平衡因子都為0,
{
parent->_bf = 0;
SubR->_bf = 0;
SubRL->_bf = 0;
}
else//發生錯誤
{
assert(false);
}
}
};
測驗代碼
#include"C++_AVL.h"
#include<vector>
void TestAVL_Insert()//檢測插入AVL樹的操作是否正確,并且檢查是否是AVL樹
{
vector<int>Arr = { 16, 4, 2,29, 9, 26, 10, 25 };
AVLTree<int, int>AVL;
for (const auto& e : Arr)
{
AVL.Insert(make_pair(e, 1));
//cout << "插入" << e << "->" << AVL.IsAVLTree() << endl;
}
AVL.PrintTree();
if (AVL.IsAVLTree())
{
cout << "AVL樹" << endl;
}
//測驗修改AVL樹的值
AVL[0] = 100;
AVL[2] = 30;
AVL.PrintTree();
}
int main()
{
TestAVL_Insert();
return 0;
}
運行結果

5.代碼Github/Gitree代碼位置
Github鏈接
Gitree鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/353388.html
標籤:其他
