AVL树的创建和插入操作
来源:互联网 发布:守望先锋数据战766 编辑:程序博客网 时间:2024/06/01 09:52
/************************************************************************* > File Name: AVLTree.c > Author: guoxiaoming > Mail: wuxinliulei@gmail.com > Created Time: 2014年03月24日 星期一 23时31分49秒 ************************************************************************/#include<stdio.h>#include<stdlib.h>typedef struct node{int data;int bf;//balance flag 平衡因子的缩写struct node *lchild , *rchild;}BitNode,*BiTree;//之所以要用** 是因为参数传递情况下 要更改指针指向内容的需要 地址传递//右调整:对以p为根的二叉树右旋 该树 左子树深度大于右子树//调整后: 根节点为p节点的左孩子,同时将p节点左孩子的右孩子接在p节点的左孩子//然后将p节点作为新根的右孩子void rightRotate(BiTree *p){BiTree L = (*p)->lchild;(*p)->lchild = L->rchild;L->rchild = (*p);*p = L;}//左调整:同理,只是将以p为根的二叉树左旋,该树的右子树深度大于左子树//调整好:根节点为p的右孩子,同时将p节点的右孩子的左孩子加在p节点的右孩子//然后将p节点作为新的根节点的左孩子void leftRotate(BiTree *p){BiTree R = (*p)->rchild;(*p)->rchild = R->lchild;R->lchild = (*p);*p = R;}//处理LL 和LR 两种类型的旋状 LL型旋转只需要右旋一次 LR型又分三种情况//但是LR型的处理方法都是先根据根节点的左孩子左旋转一次变为LL型然后再又旋转void LL_LRBalance(BiTree *p){ BiTree L = (*p)->lchild;BiTree R;switch(L->bf){case 1://若为1,则表示新节点插在左孩子的左子树上,为LL型(*p)->bf = L->bf = 0;rightRotate(p);break;case -1://若为-1,则表示插入到左孩子的右子树上,为LR型R = L->rchild;switch(R->bf){case 0:(*p)->bf = L->bf = 0; break;case 1:(*p)->bf = -1; R->bf = L->bf = 0; break;case -1:(*p)->bf = R->bf = 0; L->bf = 1; break;}leftRotate(&((*p)->lchild));rightRotate(p);break;}}void RR_RLBalance(BiTree *p){BiTree R = (*p)->rchild;BiTree L;switch(R->bf){case -1:(*p)->bf = R->bf = 0;leftRotate(p);break;case 1: L = R->lchild;switch(L->bf){case 0: (*p)->bf = R->bf = 0; break;case 1: (*p)->bf = L->bf =0; R->bf = -1; break;case -1: (*p)->bf = 1; L->bf = R->bf = 0; break;}rightRotate(&(*p)->rchild);leftRotate(p);break;}}//输入参数 p为根节点指针 key为被插入的关键字 chain表示插入节点后是否引起调整//初使为0 int insertAVL(BiTree *p,int key,int * chain){//表示未在树中找到key,直接生成新的节点,用于存储keyif((*p) == NULL){(*p) = (BitNode *) malloc (sizeof(BitNode));(*p)->bf = 0;(*p)->lchild = (*p)->rchild = NULL;(*p)->data = key;*chain = 1;} else{//表示树中有相同的关键字,表示插入失败if(key == (*p)->data){*chain = 0; return 0;}//表示插入值小于当前的结点key,则递归在当前结点的左子树插入if(key < (*p)->data){//如果插入不成功if(!insertAVL(&(*p)->lchild,key,chain)) return 0;if(*chain){//此处在递归调用退出时调用,表示新节点在p左子树插入switch((*p)->bf){//if p的平衡因子为0 那么在其左子树插入,他将变为1//树的高度增加,会产生平衡引子的变化 但不用调整case 0:(*p)->bf = 1; *chain = 1; break;//if p的平衡因子为1,那么在其左子树插入,平衡被破坏,//需要进行调整,调整之后,不会导致树的高度增加,则结束case 1: LL_LRBalance(p); *chain = 0; break;//if p的平衡因子为-1,那么在其左孩子插入节点,则bf变为0,//树的平衡没有破坏,反应结束case -1:(*p)->bf = 0; chain = 0; break;}}} else {if(!insertAVL(&(*p)->rchild,key,chain)) return 0;if(*chain){{switch((*p)->bf){case 0: (*p)->bf = -1; chain = 1; break; case 1: (*p)->bf = 0; chain = 0; break;case -1:RR_RLBalance(p); chain = 0; break;}}} }}return 1;}void InOrder(BiTree t){ if(t != NULL){InOrder(t->lchild);printf("%d ",t->data);InOrder(t->rchild);}}int main(){int i;int a[10] = {3,2,1,4,5,6,9,7,8,0};BiTree T = NULL;int chain;for(i=0;i<10;i++){insertAVL(&T,a[i],&chain);}printf("中序遍历的结果:");InOrder(T);printf("\n"); int test;printf("请输入你想插入的数据:"); scanf("%d",&test);insertAVL(&T,test,&chain);printf("中序遍历的结果:");InOrder(T);printf("\n");}
0 0
- AVL树的创建和插入操作
- AVL树的插入操作
- avl树的插入操作和删除操作
- AVL树的创建,插入算法
- 【AVL树】AVL树的插入操作以及旋转
- AVL树的旋转,插入,删除操作
- AVL树的插入删除操作
- AVL树的插入与删除操作
- 数据结构-----AVL树的插入删除操作
- AVL树的插入、删除、查找操作
- 平衡二叉树(AVL)的插入操作
- AVL树的插入删除操作
- AVL树的旋转与插入操作
- AVL的插入,删除操作
- 二叉树的基本操作(三)——AVL树的性质和插入操作
- AVL树的插入和删除
- AVL树的查找和插入
- AVL 树的插入和删除
- 第四周作业
- 关于用Java写的贪吃蛇游戏的一些感想
- 【判断奇偶】#4 A. Watermelon
- 计算机视觉资料
- spring的事务理解
- AVL树的创建和插入操作
- js中传递特殊字符&的方法
- Hash算法类
- bzoj1786
- java基础__string字符串
- android 自定义控件之折线图自己写代码,不用jar包
- 报到
- poj 1979
- Apache+Tomcat+AJP