【数据结构基础】平衡二叉树(AVL)
来源:互联网 发布:淘宝网天猫运动鞋 编辑:程序博客网 时间:2024/06/09 19:18
平衡二叉树理解起来很简单,但是把代码写出来,却不是一件很容易的事。
方法一:(代码参考一篇博客,现找不到地址)
主要是参照严蔚敏的数据结构c语言版,其中在插入时,引入平衡因子(balance factor)这一说法,而且在还要用一个变量taller来判断树是否真正长高。
#include <stdio.h> #include <stdlib.h> #define LH 1#define RH -1#define EH 0 #define TRUE 1 #define FALSE 0 typedef struct BiTNode { int data; int bf; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; void R_Rotate( BiTree *p ) { BiTree L; L = (*p)->lchild; (*p)->lchild = L->rchild; L->rchild = *p; *p = L; } void L_Rotate(BiTree *p){ BiTree R; R=(*p)->rchild; (*p)->rchild = R->lchild; R->lchild = *p; *p = R; } void LeftBalance( BiTree *T ){ BiTree L, Lr; L = (*T)->lchild; switch( L->bf ){ case 1: (*T)->bf = L->bf = 0; R_Rotate( T ); break; case -1: Lr = L->rchild; switch( Lr->bf ){ case 1: (*T)->bf = -1; L->bf = 0; break; case 0: (*T)->bf = L->bf = 0; break; case -1: (*T)->bf = 0; L->bf = 1; break; } Lr->bf = 0; L_Rotate( &(*T)->lchild ); R_Rotate( T ); } } void RightBalance( BiTree *T ){ BiTree R, Rl; R = (*T)->rchild; switch( R->bf ){ case -1: (*T)->bf = R->bf = 0; L_Rotate( T ); break; case 1: Rl = R->lchild; switch( Rl->bf ){ case 1: (*T)->bf = 0; R->bf = -1; break; case 0: (*T)->bf = R->bf = 0; break; case -1: (*T)->bf = 1; R->bf = 0; break; } Rl->bf = 0; R_Rotate( &(*T)->rchild ); L_Rotate( T ); } }int InsertAVL( BiTree *T,int e,int *taller) { if(!*T){ *T=(BiTree)malloc(sizeof(BiTNode)); (*T)->data=e; (*T)->lchild=(*T)->rchild = NULL; (*T)->bf = 0; *taller = TRUE; } else { if(e==(*T)->data ){ *taller = FALSE; return FALSE; } if(e<(*T)->data ){ if( !InsertAVL(&(*T)->lchild,e,taller)) { return FALSE; } if(*taller){ switch((*T)->bf ){ case 1: LeftBalance( T ); *taller = FALSE; break; case 0: (*T)->bf = 1; *taller = TRUE; break; case -1: (*T)->bf = 0; *taller = FALSE; break; } } } else{ if(!InsertAVL(&(*T)->rchild,e,taller)){ return FALSE; } if( *taller ){ switch((*T)->bf){ case 1: (*T)->bf = 0; *taller = FALSE; break; case 0: (*T)->bf = -1; *taller = TRUE; break; case -1: RightBalance(T); *taller = FALSE; break; } } } } return TRUE; } //preorder traversal AVLTree void Preorder_Traversal_AVL( BiTree T){ if(T){ printf("%d ",T->data); Preorder_Traversal_AVL(T->lchild); Preorder_Traversal_AVL(T->rchild); }}int main(void){ int i; int a[5]={13,24,37,90,53}; BiTree T = NULL; int taller; for( i=0;i<sizeof(a)/sizeof(int);i++){ InsertAVL(&T,a[i],&taller); } Preorder_Traversal_AVL(T); return 0;}
方法二:这是我看浙大数据结构的MOOC提供的一种方法。直接用height表示树高,每次插入结点后,利用递归的逐层返回求树高,做相应调整,个人感觉这种方法更好。
#include<stdio.h>#include<stdlib.h>typedef struct node { int key; int height; struct node *lchild, *rchild;}Node, *PNode;int Max(int a, int b) { return a>b ? a : b;}int Get_Height(PNode R) { return R == NULL ? 0 : R->height;}void LL_Rotate(PNode *R) { PNode Rl = (*R)->lchild; (*R)->lchild = Rl->rchild; Rl->rchild = *R; (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild)) + 1; Rl->height = Max(Get_Height(Rl->lchild), Get_Height(Rl->rchild)) + 1; *R = Rl;}void RR_Rotate(PNode *R) { PNode Rr = (*R)->rchild; (*R)->rchild = Rr->lchild; Rr->lchild = *R; (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild)) + 1; Rr->height = Max(Get_Height(Rr->lchild), Get_Height(Rr->rchild)) + 1; *R = Rr;}void LR_Rotate(PNode *R) { //PNode Rl = (*R)->lchild; RR_Rotate(&(*R)->lchild); LL_Rotate(R);}void RL_Rotate(PNode *R) { //PNode Rr = (*R)->rchild; LL_Rotate(&(*R)->rchild); RR_Rotate(R);}void Insert_AVL(PNode *R, int k) { if (!*R) { (*R) = (PNode)malloc(sizeof(Node)); (*R)->key = k; (*R)->height = 0; (*R)->lchild = (*R)->rchild = NULL; } else { if (k < (*R)->key) { Insert_AVL(&(*R)->lchild, k); if (Get_Height((*R)->lchild) - Get_Height((*R)->rchild) == 2) { if (k < (*R)->lchild->key) { LL_Rotate(R); } else { LR_Rotate(R); } } } if (k > (*R)->key) { Insert_AVL(&(*R)->rchild, k); if (Get_Height((*R)->lchild) - Get_Height((*R)->rchild) == -2) { if (k > (*R)->rchild->key) { RR_Rotate(R); } else { RL_Rotate(R); } } } } (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild))+1;}void Preorder_Traversal(PNode R) { if (R) { printf("%d ", R->key); Preorder_Traversal(R->lchild); Preorder_Traversal(R->rchild); }}int main(void) { PNode R = NULL; int i; int a[16] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};//测试数据来源于网络 for (i = 0; i<sizeof(a) / sizeof(int); i++) { Insert_AVL(&R, a[i]); } Preorder_Traversal(R); return 0;}
~完
阅读全文
0 0
- 【数据结构基础】平衡二叉树(AVL)
- 数据结构 - 平衡二叉树 AVL
- 数据结构-AVL二叉平衡树
- 数据结构:AVL树(平衡二叉树)
- 数据结构:平衡二叉树(AVL树)
- 【数据结构】平衡二叉树之AVL树
- 数据结构:平衡二叉树(AVL树)
- 数据结构 — AVL树(平衡二叉树)
- 数据结构-平衡搜索二叉树(AVL树)
- 【数据结构重温】平衡二叉树(AVL)
- 数据结构之平衡二叉树AVL
- 数据结构--树论--平衡二叉树(AVL TREE)
- 数据结构-平衡二叉树(AVL Tree)
- 数据结构与算法10: 平衡二叉树AVL(AVL Tree)
- AVL 平衡二叉树
- 平衡二叉树(AVL)
- 平衡二叉树(AVL)
- AVL 平衡二叉树
- 如何用代码在Delphi 7.0中安装TeeChart 7.0
- uva 10976 Fractions Again?!
- 查询ICCID,找回被盗iPhone
- Windows下nginx安装与配置
- Java选择题
- 【数据结构基础】平衡二叉树(AVL)
- 2017-08-14
- Maven介绍,安装以及创建项目
- HTML的标签总结
- CNN结构:用于检测的CNN结构进化-分离式方法
- MySQL重置root密码方法
- Spring的传播行为与隔离级别
- px、em、rem、%、vw、wh、vm等单位有什么区别?
- 【Tomcat】-- Tomcat + Nginx反向代理https和wss并解决获取客户端真实IP、域名、协议、端口