显示旋转过程的AVL树

来源:互联网 发布:sor文件打开软件 编辑:程序博客网 时间:2024/05/16 05:00

这是我第一次在csdn上面写博客。以前遇到不会的问题时,csdn总有一片博文能为我解惑,今天我也打算上传一些代码来为这个社区做贡献。笔者不才,代码常有纰漏之处,愿有幸读到这篇博文的同学不吝赐教。

下面的代码是一颗AVL树的插入代码,随着插入的进行,树会根据左右子树的高度来进行调整,并且会把步骤显示出来,不过步骤的显示并没有独立做成函数,而是嵌在代码中,这在一定程度上影响了程序的可读性,读者可以先把cout部分的代码略去,以观察旋转过程。需要提醒,旋转的函数我用了c++里面的引用,所以并没有传值出去,函数类型为void。

#include<cctype>#include<iostream>#include<stack>#include<queue>#include<array>typedef struct TNode *BinTree;struct TNode{//树的结点的结构体,包含一个整数数值,指向左子树的指针,指向右子树的指针,和该结点的高度 int data;BinTree left;BinTree right;int height;};using namespace std;int GetHeight(BinTree BT) //该函数功能是读取该节点的高度并返回该值 {if( !BT ) return 0;else{return (GetHeight(BT->left) > GetHeight(BT->right) ? GetHeight(BT->left) :GetHeight(BT->right) )+1;}}void Sgl_left(BinTree &BT) //左单旋的过程,如果觉得不易阅读可以先忽略掉cout开头的语句 {BinTree tmp = BT->left;cout<<tmp->data<<"的右子树移到 "<<BT->data<<" 的左子树\n";cout<<"结点 "<<BT->data<<" 移到结点 "<<tmp->data<<" 的右子树"<<endl<<endl; BT->left = tmp->right;tmp->right = BT;BT = tmp;//注意在每次旋转过后都要更新结点的高度 BT->height = (GetHeight(BT->left) > GetHeight(BT->right) ? GetHeight(BT->left):GetHeight(BT->right))+1;}void Sgl_right(BinTree &BT){BinTree tmp = BT->right;cout<<tmp->data<<"的左子树移到 "<<BT->data<<" 的右子树\n";cout<<"结点 "<<BT->data<<" 移到结点 "<<tmp->data<<" 的左子树"<<endl<<endl; BT->right = tmp->left; tmp->left = BT;BT = tmp;BT->height = (GetHeight(BT->left) > GetHeight(BT->right) ? GetHeight(BT->left):GetHeight(BT->right))+1;}void Dbl_left_right(BinTree &BT)//左右双旋 {BinTree &tmp = BT->left;Sgl_right(tmp);Sgl_left(BT);}void Dbl_right_left(BinTree &BT)//右左双旋 {BinTree &tmp = BT->right;Sgl_left(tmp);Sgl_right(BT);}BinTree AVL_insert(BinTree BT,int data){if(!BT) //如果结点空,说明找到了该插入的位置,那么,插入之。 {BT = new TNode;BT->data = data;BT->height = 0;BT->left = BT->right  = NULL;}else{if( data > BT->data) //值比该结点的要大,递归插入到该结点的右子树 {BT->right = AVL_insert(BT->right,data);if(GetHeight(BT->left) - GetHeight(BT->right) == -2)//插入完成后判断树是否平衡,如果不平衡,先判断如何旋转,再调用函数旋转 {cout<<"根为 "<<BT->data<<" 的树右子树高度比左子树低2," ; if(data > BT->right->data) {cout<<"插入的节点的值 "<<data<<" 比树根为 "<<BT->data<<" 的树的右子树的值要大!\n"<<"所以进行右单旋\n"; Sgl_right(BT);}else{cout<<"插入的节点的值 "<<data<<" 比树根为 "<<BT->data<<" 的树的右子树的值要小!\n"<<"所以进行右左双旋\n"; Dbl_right_left(BT);} }}else if(data < BT->data) //如果待插入的值比该结点小,则递归的插入到该节点的右子树 {BT->left = AVL_insert(BT->left,data);if(GetHeight(BT->left) - GetHeight(BT->right) == 2){cout<<"根为 "<<BT->data<<" 的树左子树高度比右子树高2," ; if(data < BT->left->data ){cout<<"插入的节点的值 "<<data<<" 比树根为 "<<BT->data<<" 的树的左子树的值要小!\n"<<"所以进行左单旋\n"; Sgl_left(BT);}else{cout<<"插入的节点的值 "<<data<<" 比树根为 "<<BT->data<<" 的树的左子树的值要大!\n"<<"所以进行左右双旋\n"; Dbl_left_right(BT);} }}}//更新结点的高度 int max = (GetHeight(BT->left) > GetHeight(BT->right) ? GetHeight(BT->left):GetHeight(BT->right))+1;BT->height = max;return BT;}//层序遍历 void Level_trav(BinTree BT){queue<BinTree>q;q.push(BT);BinTree Tmp = NULL;while( !q.empty()){Tmp = q.front();q.pop();cout<<Tmp->data<<" ";if(Tmp->left) q.push(Tmp->left);if(Tmp->right) q.push(Tmp->right);}}int main(){int tmp ;BinTree BT = NULL;//这是测试数据 array<int,20> test = {12,9,7,6,8,49,63,34,77,-7,0,83,88,106,-79,-63,32,7,49,-49}; for(int i = 0;i<20;i++){cout<<"第"<<i+1<<"个结点:"<<test[i]<<endl<<endl; BT = AVL_insert(BT,test[i]);}cout<<"层序遍历这棵树:";Level_trav(BT);return 0;}


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电线多少钱一卷 电线电缆批发市场 电线电缆制造厂 电线电缆载流量表 旧电线电缆回收 电线电缆哪个牌子好 普通电线价格 4平方国标电线多少钱 广东电线品牌 红旗电线电缆价格表 电线电缆价钱 民兴电线电缆 电线电缆品牌 废电缆电线回收 电线电缆厂家 高压电线电缆价格 废旧电线电缆剥皮机 电线电缆国标 4平方电线价格 回收电线电缆 电线电缆的价格 4平方电线多少钱一卷 电线电缆安全载流量表 环保电线电缆 电线电缆回收哪家好 高压电线电缆 全国电线电缆排名 电线电缆型号 正一电线电缆 电线电缆生产设备 阻燃电线型号 电缆电线回收 电缆电线品牌 高价回收电线电缆 电线电缆企业 国标电线电缆 电线电缆规格型号表 电线电缆曲挠试验机 起帆电线怎么样 电缆品牌 铜线价格