16-1平衡树源代码
生活随笔
收集整理的這篇文章主要介紹了
16-1平衡树源代码
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
本例子分為3個文件。
類聲明頭文件 hAVL.h #ifndef AVLTREE_H_INCLUDED #define AVLTREE_H_INCLUDED//AVL樹數(shù)據(jù)結(jié)構(gòu)定義 typedef int ElementType;//AVL數(shù)節(jié)點包含數(shù)據(jù)類型//樹節(jié)點 typedef struct AVLNode{ElementType element;//節(jié)點包含的數(shù)據(jù)元素AVLNode *left;//節(jié)點左子樹AVLNode *right;//節(jié)點右子樹int height;//節(jié)點所在的高度 }*AVLTree;//AVL tree類封裝 class CAVLTree{ private://供內(nèi)部調(diào)用的函數(shù)int getHeight(AVLTree);//求得樹的高度void setHeight(AVLTree, int);//設(shè)置節(jié)點的高度值//單旋轉(zhuǎn):向右旋轉(zhuǎn) AVLTree SingleRightRotate(AVLTree);//單旋轉(zhuǎn):向左旋轉(zhuǎn) AVLTree SingleLeftRotate(AVLTree);//雙旋轉(zhuǎn):左右 AVLTree DoubleRightRotate(AVLTree);//雙旋轉(zhuǎn):右左 AVLTree DoubleLeftRotate(AVLTree);public://默認(rèn)構(gòu)造函數(shù) CAVLTree();//析構(gòu)函數(shù)~CAVLTree();//創(chuàng)建AVL樹void createAVLTree(ElementType *data, int n);//插入節(jié)點 AVLTree insertNode(AVLTree T, ElementType val);//刪除樹中元素值等于某值的節(jié)點AVLTree deleteNode(AVLTree T, const ElementType val);//搜尋元素值等于某值的節(jié)點 AVLTree searchNode(AVLTree, ElementType);//前序遍歷輸出樹void preOrder(AVLTree T);//得到樹中的元素值最大的節(jié)點 AVLTree getMaxNode(AVLTree);//得到樹中的元素值最小的那個節(jié)點 AVLTree getMinNode(AVLTree);void deleteTree(AVLTree t);AVLTree T; };#endif // AVLTREE_H_INCLUDED //右右外側(cè)插入導(dǎo)致的不平衡,采用單旋轉(zhuǎn)-左旋轉(zhuǎn)進(jìn)行修正 //參數(shù)解釋:類實現(xiàn)文件AVLTr.cpp #include "stdafx.h" #include "hAVL.h"#include <iostream> #include <cmath> #include <math.h> #include <cassert>using namespace std;int fmax(int i, int j) {return i>j?i:j; };CAVLTree::CAVLTree() {T = NULL; }CAVLTree::~CAVLTree() {deleteTree(T); }//依據(jù)各元素的數(shù)據(jù)值,創(chuàng)建AVL樹 void CAVLTree::createAVLTree(ElementType *data, int n) {if (T){cout << "The AVL Tree has been created" << endl;return;}if (!n)//元素序列為空 {T = NULL;return;}for (int i = 0; i < n; ++i){T = insertNode(T, *(data + i));}return; }AVLTree CAVLTree::insertNode(AVLTree T, ElementType val) {AVLNode *pNewNode = new AVLNode;pNewNode->element = val;pNewNode->left = NULL;pNewNode->right = NULL;pNewNode->height = 1;//新節(jié)點一定被插入在空節(jié)點的位置if (NULL == T){T = pNewNode;return T;}//需要插入節(jié)點的樹非空//插入的元素已經(jīng)存在于樹中,不符合要求if (val == T->element){cout << "元素中有重復(fù),構(gòu)建AVL樹失敗!" << endl;return T;}//要插入的值小于根節(jié)點的值,將其插入左子樹中if (val < T->element){//將其插入根節(jié)點的左子樹中T->left = insertNode(T->left, val);//判斷平衡條件是否仍然滿足if (getHeight(T->left) - getHeight(T->right) > 1){//分兩種情況進(jìn)行旋轉(zhuǎn)操作//插入點位于T的左子結(jié)點的左子樹if (val < T->left->element)//實施單旋轉(zhuǎn)-右旋轉(zhuǎn)T = SingleRightRotate(T);else//插入點位于T的左子結(jié)點的右子樹,實施雙右旋轉(zhuǎn)T = DoubleRightRotate(T);}}//要插入的值大于根節(jié)點的值,將其插入右子樹中if (val > T->element){T->right = insertNode(T->right, val);//判斷平衡條件是否仍然滿足if (getHeight(T->right) - getHeight(T->left) > 1){//節(jié)點插入到T的右子節(jié)點的右子樹中if (val > T->right->element)//實施單旋轉(zhuǎn)-左旋轉(zhuǎn)T = SingleLeftRotate(T);else//節(jié)點插入到T的右子節(jié)點的左子樹上//實施雙旋轉(zhuǎn)-左旋轉(zhuǎn)T = DoubleLeftRotate(T);}}//更新節(jié)點的height值setHeight(T, fmax(getHeight(T->left), getHeight(T->right)) + 1);return T; }AVLTree CAVLTree::deleteNode(AVLTree T, const ElementType val) {if (!T){cout << "The tree is NULL, delete failed" << endl;return T;}AVLTree searchedNode = searchNode(T, val);//沒有找到相應(yīng)的節(jié)點,刪除失敗if (!searchedNode){cout << "Cann't find the node to delete " << val << endl;return T;}//找到了需要刪除的節(jié)點//需要刪除的節(jié)點就是當(dāng)前子樹的根節(jié)點if (val == T->element){//左右子樹都非空if (T->left && T->right){//在高度更大的那個子樹上進(jìn)行刪除操作if (getHeight(T->left) > getHeight(T->right)){//左子樹高度大,刪除左子樹中元素值最大的那個節(jié)點,同時將其值賦值給根節(jié)點T->element = getMaxNode(T->left)->element;T->left = deleteNode(T->left, T->element);}else{//刪除右子樹中元素值最小的那個節(jié)點,同時將其值賦值給根節(jié)點T->element = getMinNode(T->right)->element;T->right = deleteNode(T->right, T->element);}}else{//左右子樹中有一個不為空,那個直接用需要被刪除的節(jié)點的子節(jié)點替換之即可AVLTree oldNode = T;T = (T->left ? T->left : T->right);delete oldNode;//釋放節(jié)點所占的空間oldNode = NULL;}}else if (val < T->element)//要刪除的節(jié)點在左子樹中 {//在左子樹中進(jìn)行遞歸刪除T->left = deleteNode(T->left, val);//判斷是否仍然滿足平衡條件if (getHeight(T->right) - getHeight(T->left) > 1){if (T->right->left > T->right->right){//左雙旋轉(zhuǎn)T = DoubleLeftRotate(T);}else//進(jìn)行左單旋轉(zhuǎn)T = SingleLeftRotate(T);}else//滿足平衡條件,需要更新高度信息T->height = fmax(getHeight(T->left), getHeight(T->right)) + 1;}else//需要刪除的節(jié)點在右子樹中 {T->right = deleteNode(T->right, val);//判斷是否滿足平衡條件if (getHeight(T->left) - getHeight(T->right) > 1){if (getHeight(T->left->right) > getHeight(T->left->left))//右雙旋轉(zhuǎn)T = DoubleRightRotate(T);else//右單旋轉(zhuǎn)T = SingleRightRotate(T);}else//只需調(diào)整高度即可T->height = fmax(getHeight(T->left), getHeight(T->right)) + 1;}return T; }AVLTree CAVLTree::searchNode(AVLTree T, ElementType val) {if (!T){return NULL;}//搜索到if (val == T->element){return T;}else if (val < T->element){//在左子樹中搜索return searchNode(T->left, val);}else{//在右子樹中搜索return searchNode(T->right, val);} }void CAVLTree::preOrder(AVLTree T) {if (!T)cout << "NULL ";else{cout << T->element << " ";preOrder(T->left);preOrder(T->right);} }AVLTree CAVLTree::getMaxNode(AVLTree T) {if (!T)//樹為空 {return NULL;}AVLTree tempNode = T;//向右搜尋直至右子節(jié)點為NULLwhile (tempNode->right){tempNode = tempNode->right;}return tempNode; }AVLTree CAVLTree::getMinNode(AVLTree T) {if (!T)//樹為空 {return NULL;}AVLTree tempNode = T;//向左搜尋直至左子結(jié)點為NULLwhile (tempNode->left){tempNode = tempNode->left;}return tempNode; }int CAVLTree::getHeight(AVLTree T) {return (T == NULL) ? 0 : (T->height); }void CAVLTree::setHeight(AVLTree T, int height) {T->height = height; }//左左外側(cè)插入導(dǎo)致的不平衡,采用單旋轉(zhuǎn)-右旋轉(zhuǎn)進(jìn)行修正 //參數(shù)解釋: //T:指向因某種操作失去平衡的最小子樹根節(jié)點 AVLTree CAVLTree::SingleRightRotate(AVLTree T) {AVLTree xPNode = T;AVLTree yPNode = T->left;xPNode->left = yPNode->right;//更改原根節(jié)點的左子樹yPNode->right = xPNode;//更改原根節(jié)點左孩子的右子樹//更新進(jìn)行了旋轉(zhuǎn)操作的節(jié)點的高度xPNode->height = fmax(getHeight(xPNode->left), getHeight(xPNode->right)) + 1;yPNode->height = fmax(getHeight(yPNode->left), getHeight(yPNode->right)) + 1;//原根節(jié)點的左孩子節(jié)點成為新的根節(jié)點return yPNode;//T:指向因某種操作失去平衡的最小子樹根節(jié)點 AVLTree CAVLTree::SingleLeftRotate(AVLTree T) {AVLTree xPNode = T;AVLTree yPNode = T->right;xPNode->right = yPNode->left;//更改原根節(jié)點的右孩子yPNode->left = xPNode;//提升原根節(jié)點的右孩子節(jié)點為新的根節(jié)點//更新執(zhí)行了旋轉(zhuǎn)操作的節(jié)點的高度信息xPNode->height = fmax(getHeight(xPNode->left), getHeight(xPNode->right)) + 1;yPNode->height = fmax(getHeight(yPNode->left), getHeight(yPNode->right)) + 1;//返回新的根節(jié)點return yPNode; }//插入點位于T的左子結(jié)點的右子樹 AVLTree CAVLTree::DoubleRightRotate(AVLTree T) {//雙旋轉(zhuǎn)可以通過兩次單旋轉(zhuǎn)實現(xiàn)//第一次單旋轉(zhuǎn)assert(T->left != NULL);//對其左子樹進(jìn)行一次單旋轉(zhuǎn)-左旋轉(zhuǎn)T->left = SingleLeftRotate(T->left);//第二次單旋轉(zhuǎn)//對新產(chǎn)生的樹進(jìn)行一次單旋轉(zhuǎn)-右旋轉(zhuǎn)return SingleRightRotate(T); }//插入點位于T的右子節(jié)點的左子樹 AVLTree CAVLTree::DoubleLeftRotate(AVLTree T) {//雙旋轉(zhuǎn)可以通過兩次單旋轉(zhuǎn)實現(xiàn)//第一次單旋轉(zhuǎn)assert(T->right != NULL);//對其右子樹進(jìn)行一次單旋轉(zhuǎn)-右旋轉(zhuǎn)T->right = SingleRightRotate(T->right);//第二次單旋轉(zhuǎn)//對新產(chǎn)生的樹進(jìn)行一次單旋轉(zhuǎn)-左旋轉(zhuǎn)return SingleLeftRotate(T); }void CAVLTree::deleteTree(AVLTree t) {if (NULL == t)return;deleteTree(t->left);deleteTree(t->right);delete t;t = NULL; } 主函數(shù)文件 main.cpp // AVLTree.cpp : 定義控制臺應(yīng)用程序的入口點。 // #include "stdafx.h"//平衡二叉樹搜索樹(AVL tree-Adelson-Velskii-Landis tree)編程實現(xiàn) #include "hAVL.h" #include <iostream> using namespace std;int main() {// 通過給定序列創(chuàng)建平衡二叉樹const int NumElements = 8;cout << "AVL樹各項操作編程實現(xiàn):" << endl;int a[NumElements] = { 25,2,64,45,12,34,9,18};CAVLTree *CAVLTreeObj1 = new CAVLTree();CAVLTreeObj1->createAVLTree(a, NumElements);cout << "AVL Tree先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T);cout << endl;// 插入一個新的數(shù)據(jù)int insertedVal1 = 15;CAVLTreeObj1->T = CAVLTreeObj1->insertNode(CAVLTreeObj1->T, insertedVal1);cout << "向AVL樹中插入元素 " << insertedVal1 << "之后的先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T);cout << endl << endl;// 在插入一個新的數(shù)據(jù)(由重復(fù)數(shù)據(jù)情況下)int insertedVal2 = 16;CAVLTreeObj1->T = CAVLTreeObj1->insertNode(CAVLTreeObj1->T, insertedVal2);cout << "向AVL樹中插入元素 " << insertedVal2 << "之后的先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T);cout << endl << endl;// 尋找最小的元素int minVal = CAVLTreeObj1->getMinNode(CAVLTreeObj1->T)->element;cout << "樹中最小的元素是:" << minVal << endl;cout << endl;// 尋找最大的元素int maxVal = CAVLTreeObj1->getMaxNode(CAVLTreeObj1->T)->element;cout << "樹中最大的元素是:" << maxVal << endl;cout << endl;// 刪除1個元素const int deletedVal1 = 11;CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal1);cout << "刪除元素值為 " << deletedVal1 << "的節(jié)點之后的樹先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T); cout << endl << endl;// 刪除第2個元素const int deletedVal2 = 20;CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal2);cout << "刪除元素值為 " << deletedVal2 << "的節(jié)點之后的樹先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T);cout << endl << endl;// 刪除第3個元素const int deletedVal3 = 18;CAVLTreeObj1->T = CAVLTreeObj1->deleteNode(CAVLTreeObj1->T, deletedVal3);cout << "刪除元素值為 " << deletedVal3 << "的節(jié)點之后的樹先序遍歷結(jié)果:" << endl;CAVLTreeObj1->preOrder(CAVLTreeObj1->T);cout << endl << endl;const int searchedVal1 = 12;AVLTree searchedPNode = CAVLTreeObj1->searchNode(CAVLTreeObj1->T, searchedVal1);if (!searchedPNode)cout << "cannot find such node whose elemen equals " << searchedVal1 << endl;elsecout << "search success element " << searchedVal1 << endl;const int searchedVal2 = 13;searchedPNode = CAVLTreeObj1->searchNode(CAVLTreeObj1->T, searchedVal2);if (!searchedPNode)cout << "cannot find such node whose elemen equals " << searchedVal2 << endl;elsecout << "search success element " << searchedVal2 << endl;cout << endl << endl;getchar();return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/gd-luojialin/p/8509131.html
總結(jié)
以上是生活随笔為你收集整理的16-1平衡树源代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: phpStydy配置memcache扩展
- 下一篇: go 解析身份证