AVL树C代码
来源:互联网 发布:淘宝有聊天壁纸设置吗 编辑:程序博客网 时间:2024/05/02 00:34
/*(2) 前序、中序、后序遍历二叉树 (递归) (3) 前序、中序、后序遍历的非递归算法 (4) 层次遍历二叉树 (5) 在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6) 交换各结点的左右子树 (7) 求二叉树的深度 (8) 叶子结点数 (9) 删除某结点 */ #include<stdio.h> //引用头文件stdio.h #include<stdlib.h> //引用头文件stdlib.h #include<malloc.h> //引用头文件malloc.h #define MAXSIZE 100 //用#define定义全局变量MAXSIZE的值为100 #define OK 1 //用#define定义全局变量OK的值为1 #define ERROR 0 //用#define定义全局变量ERROR的值为0 typedef int Status; //定义Status为int类型来表示函数返回值状态 typedef int ElemType; //定义ElemType为int类型来表示元素类型 typedef struct BSTNode //定义平衡二叉树结构体 { ElemType data; //结点存储的数据 int height; //结点的高度 struct BSTNode *lchild,*rchild; //左、右孩子指针 }BSTNode,*BSTree; typedef BSTree Position; //定义Position为BSTree来表示节点树中位置 typedef struct //定义栈的结构体 { BSTree *base; //在栈构造前和销毁后,base的值为NULL BSTree *top; //栈顶指针 int stacksize; //当前已分配的存储空间,以元素为单位 }Stack; typedef struct //定义队列的结构体 { BSTree *front; //队头指针 BSTree *rear; //队尾指针 int queuesize; //当前已分配的存储空间,以元素为单位 }Queue; Status InsertBST(BSTree &T,ElemType e); //实现树的节点的插入 Status PreOrderTraverse(BSTree T); //实现树的递归前序遍历 Status InOrderTraverse(BSTree T); //实现树的递归中序遍历 Status PostOrderTraverse(BSTree T); //实现树的递归后序遍历 Status AllOrderTraverse(BSTree T); //实现三种递归遍历的打印 Status NonPreOrder(BSTree T,Stack S); //实现树的非递归前序遍历 Status NonInOder(BSTree T,Stack S); //实现树的非递归中序遍历 Status NonPostOrder(BSTree T,Stack S); //实现树的非递归后序遍历 Status NonAllOrder(BSTree T,Stack S); //实现三种非递归遍历的打印 Status LevelTraverse(BSTree T,Queue Q); //实现二叉树的层次遍历 Status PostsSearch(BSTree T,ElemType e);//实现二叉树中给定关键字的查找 Status SwapSubtree(BSTree T); //实现结点左右子树的交换 int TreeDepth(BSTree T); //实现二叉树深度的求值 int TotalNodeNum(BSTree T); //实现二叉树总结点数的求值 int LeafNodeNum(BSTree T); //实现二叉树叶子结点数的求值 Status DeleteBST(BSTree &T,ElemType e); //实现树的节点的删除 int TreeHeight(BSTree T); //实现树的高度的求值 int Max(int a,int b); //实现两个数中求最大值 Position MinElemSearch(BSTree T); //实现最小元素的查找 BSTree LeftRotate(BSTree g); //实现二叉树一次右旋转操作 BSTree RightRotate(BSTree g); //实现二叉树一次左旋转操作 BSTree L_RRotate(BSTree g); //实现一次先左旋转再右旋转操作 BSTree R_LRotate(BSTree g); //实现一次先右旋转再左旋转操作 Status CreatStack(Stack &S); //实现栈的建立 Status CreatQueue(Queue &Q); //实现队列的建立 Status InsertBST(BSTree &T,ElemType e) //实现在二叉树中插入新结点的函数 { if(T==NULL) //判断是否为空树,是则建建立一个根节点给树 { T=(BSTree)malloc(sizeof(BSTNode)); if(!T) //判断该节点是否建立失败 return ERROR; T->data=e; T->height=0; //根节点时,高度为0 T->lchild=T->rchild=NULL; } else if(e<T->data) //如果输入的元素比节点数据小,则向左插入 { InsertBST(T->lchild,e); //递归调用该函数本身 if(TreeHeight(T->lchild)-TreeHeight(T->rchild)==2) { //判断二叉树是否出现不平衡状态,是则进入该分支 if(e<T->lchild->data) //若输入的数据比左孩子结点的数据小,则进行右旋转 T=LeftRotate(T); else //否则先进行左旋转再右旋转 T=L_RRotate(T); } } else if(e>T->data) //如果输入的元素比节点数据大,则向右插入 { InsertBST(T->rchild,e); //递归调用该函数本身 if(TreeHeight(T->rchild)-TreeHeight(T->lchild)==2) { //判断二叉树是否出现不平衡状态,是则进入该分支 if(e>T->rchild->data) //若输入的数据比右孩子结点的数据大,则进行左旋转 T=RightRotate(T); else //否则先进行右旋转再左旋转 T=R_LRotate(T); } } //如果输入数据与节点数据相等,不需要进行操作 T->height=Max(TreeHeight(T->lchild),TreeHeight(T->rchild))+1; return OK; //最后需要记录节点高度 } Status PreOrderTraverse(BSTree T) //实现递归前序遍历函数 { if(T!=NULL) //判断是否为空树 { printf("%d ",T->data); PreOrderTraverse(T->lchild); PreOrderTraverse(T->rchild); } return OK; } Status InOrderTraverse(BSTree T) //实现递归中序遍历函数 { if(T!=NULL) //判断是否为空树 { InOrderTraverse(T->lchild); printf("%d ",T->data); InOrderTraverse(T->rchild); } return OK; } Status PostOrderTraverse(BSTree T) //实现递归后序遍历函数 { if(T!=NULL) //判断是否为空树 { PostOrderTraverse(T->lchild); PostOrderTraverse(T->rchild); printf("%d ",T->data); } return OK; } Status AllOrderTraverse(BSTree T) //实现各种递归遍历打印函数 { printf("\n\t递归前序遍历如下:\n\t"); PreOrderTraverse(T); printf("\n"); printf("\n\t递归中序遍历如下:\n\t"); InOrderTraverse(T); printf("\n"); printf("\n\t递归后序遍历如下:\n\t"); PostOrderTraverse(T); printf("\n"); return OK; } Status NonPreOrder(BSTree T,Stack S) //实现非递归前序遍历函数 { while(S.base!=S.top||T!=NULL) //判断栈和树是否为空 { while(T!=NULL) //向左子树一直循环到最左的节点 { printf("%d ",T->data); //输出元素 *S.top++=T; T=T->lchild; } T=*--S.top; //实现出栈 T=T->rchild; //转向右子树 } return OK; } Status NonInOder(BSTree T,Stack S) //实现非递归中序遍历函数 { while(S.base!=S.top||T!=NULL) //判断栈和树是否为空 { while(T!=NULL) //向左子树一直循环到最左的节点 { *S.top++=T; T=T->lchild; } T=*--S.top; //实现出栈 printf("%d ",T->data); //输出元素 T = T->rchild; //转向右子树 } return OK; } Status NonPostOrder(BSTree T,Stack S) //实现非递归后序遍历函数 { BSTree temp=NULL; //定义临时变量,用来标记刚刚访问过的节点 while(S.base!=S.top||T!= NULL) //判断栈和树是否为空 { while(T!=NULL) //向左子树一直循环到最左的节点 { *S.top++=T; T=T->lchild; } T=*(S.top-1); //取栈顶节点 if(T->rchild==NULL||T->rchild==temp) { //如果该节点没有右孩子或者其右孩子刚刚被访问过 printf("%d ",T->data); //输出元素 S.top--; //已访问,使其出栈 temp=T; //标记为刚刚访问过 T=NULL; //若遍历完以该节点为根的子树,且栈空,则结束,否则继续 } else T=T->rchild; //转向右子树 } return OK; } Status NonAllOrder(BSTree T,Stack S) //实现各种非递归遍历打印函数 { printf("\n\t非递归前序遍历如下:\n\t"); CreatStack(S); NonPreOrder(T,S); printf("\n"); printf("\n\t非递归中序遍历如下:\n\t"); CreatStack(S); NonInOder(T,S); printf("\n"); printf("\n\t非递归后序遍历如下:\n\t"); CreatStack(S); NonPostOrder(T,S); printf("\n"); return OK; } Status LevelTraverse(BSTree T,Queue Q) //实现层次遍历函数 { if(T!=NULL) { *Q.rear++=T; while(Q.front!=Q.rear) //判断队列是否为空 { if(T->lchild!=NULL) //判断左子树是否为空 *Q.rear++=T->lchild; //左子树进队 if(T->rchild!=NULL) //判断右子树是否为空 *Q.rear++=T->rchild; //右子树进队 T=*Q.front++; //实现出队操作 printf("%d ",T->data); T=*Q.front; //此时的队头元素 } } return OK; } Status PostsSearch(BSTree T,ElemType e) //实现在二叉树中查找给定关键字函数 { if(T!=NULL) //判断二叉树是否为空 { if(e==T->data) //判断查找值是否与节点数据相等 return OK; else if(e<T->data) return PostsSearch(T->lchild,e);//查找值小于节点数据,则进入左子树查找 else return PostsSearch(T->rchild,e);//查找值大于节点数据,则进入右子树查找 } else return ERROR; } Status SwapSubtree(BSTree T) //实现交换各结点的左右子树函数 { BSTree temp; //定义临时变量 if(T!=NULL) //判断二叉树是否为空 { temp=T->lchild; T->lchild=T->rchild; T->rchild=temp; SwapSubtree(T->lchild); SwapSubtree(T->rchild); } return OK; } int TreeDepth(BSTree T) //实现求二叉树的深度函数 { int deep,ldeep=0,rdeep=0; if(T!=NULL) //判断二叉树是否为空 { ldeep=TreeDepth(T->lchild); rdeep=TreeDepth(T->rchild); deep=Max(ldeep,rdeep)+1; } else return 0; return deep; } int TotalNodeNum(BSTree T) //实现统计总的结点数函数 { int sum=0,lsum=0,rsum=0; if(T!=NULL) //判断二叉树是否为空 { lsum=TotalNodeNum(T->lchild); rsum=TotalNodeNum(T->rchild); sum=lsum+rsum+1; return sum; } else return 0; } int LeafNodeNum(BSTree T) //实现统计叶子结点数函数 { int dot=0,ldot=0,rdot=0; if(T!=NULL) //判断二叉树是否为空 { if(T->lchild==NULL&&T->rchild==NULL) //判断是否只含有一个节点 dot=1; else { ldot=LeafNodeNum(T->lchild); rdot=LeafNodeNum(T->rchild); dot=ldot+rdot; } } else return 0; return dot; } Status DeleteBST(BSTree &T,ElemType e) //实现在二叉树中删除某结点的函数 { Position temp; //定义临时变量 if(T==NULL) //判断二叉树是否为空 return ERROR; else if(e<T->data) //需要删除的数据比节点数据小的情况 return DeleteBST(T->lchild,e); //继续调用函数本身进入左子树查找 else if(e>T->data) //需要删除的数据比节点数据大的情况 return DeleteBST(T->rchild,e); //继续调用函数本身进入右子树查找 else //即需要删除的数据与节点数据相等的情况 { if(T->lchild!=NULL&&T->rchild!=NULL) { //左右孩子都存在的情况 temp=MinElemSearch(T->rchild); //在右子树中找到最小的节点 T->data=temp->data; //用找到的最小节点的数据代替要删除的节点的数据 DeleteBST(T->rchild,T->data); //删除右子树刚刚找到的最小的节点 } else //有一个孩子或者没有孩子的情况 { temp=T; if(T->lchild==NULL) //判断是否没有孩子的情况 T=T->rchild; else if(T->rchild==NULL) //判断是否有一个孩子的情况 T=T->lchild; free(temp); } return OK; } } int TreeHeight(BSTree T) //实现求树的高度的函数 { if(T==NULL) //判断二叉树是否为空 return -1; else return T->height; } int Max(int a,int b) //实现求较大值的函数 { return a>b?a:b; //三元运算符,哪个值大返回哪个 } Position MinElemSearch(BSTree T) //实现查找最小元素的函数 { if(T==NULL) //判断二叉树是否为空 return NULL; else if(T->lchild==NULL) //判断是否为没有子树的情况 return T; else return MinElemSearch(T->lchild); } /* 100 85 / \ 右旋 / \ 85 120 ------ -> 60 100 / \ \ / \ 60 90 80 90 120 \ 80*/ BSTree LeftRotate(BSTree g) //实现树的向右旋转函数 { BSTree temp; temp=g->lchild; g->lchild=temp->rchild; temp->rchild=g; temp->height=Max(TreeHeight(temp->lchild),g->height)+1; g->height=Max(TreeHeight(g->lchild),TreeHeight(g->rchild))+1; return temp; //返回新的根节点 } /* 80 90 / \ 左旋 / \ 60 90 ---- -> 80 120 / \ / \ / 85 120 60 85 100 / 100 */ BSTree RightRotate(BSTree g) //实现树的向左旋转函数 { BSTree temp; temp=g->rchild; g->rchild=temp->lchild; temp->lchild=g; g->height=Max(TreeHeight(g->lchild),TreeHeight(g->rchild))+1; temp->height=Max(TreeHeight(g->rchild),g->height)+1; return temp; //返回新的根节点 } /* 100 100 90 / \ 左旋 / \ 右旋 / \ 80 120 ------> 90 120 ------> 80 100 / \ / / \ \ 60 90 80 60 85 120 / / \ 85 60 85 */BSTree L_RRotate(BSTree g) //实现树的向左旋转再向右旋转函数 { g->lchild=RightRotate(g->lchild); //先左旋转 return LeftRotate(g); //再右旋转 } /* 80 80 85 / \ 右 旋 / \ 左 旋 / \ 60 100 ------> 60 85 -------> 80 100 / \ \ / / \ 85 120 100 60 90 120 \ / \ 90 90 120*/ BSTree R_LRotate(BSTree g) //实现树的向右旋转再向左旋转函数 { g->rchild=LeftRotate(g->rchild); //先右旋转 return RightRotate(g); //再左旋转 } Status CreatStack(Stack &S) //实现栈的建立函数 { S.base=(BSTree*)malloc(MAXSIZE*sizeof(BSTree)); if(!S.base) //判断是否建立失败 return ERROR; S.top=S.base; S.stacksize=MAXSIZE; return OK; } Status CreatQueue(Queue &Q) //实现队列的建立函数 { Q.front=(BSTree*)malloc(MAXSIZE*sizeof(BSTree)); if(!Q.front) //判断是否建立失败 return ERROR; Q.rear=Q.front; Q.queuesize=MAXSIZE; return OK; } int main() //主函数 { ElemType k,e,d; int i,n,ch; char c; BSTree T=NULL; Stack S; Queue Q; printf("\n\t运行本程序需要先构造一个二叉树!\n"); printf("\n\t请输入需要插入的元素个数:"); scanf("%d",&n); if(n==0) { printf("\n\t成功创建一个空二叉树!",n); c=getchar(); //用来吸收多余字符 c=getchar(); //用来吸收多余字符 } else { printf("\n\t请输入要插入的%d个元素:",n); for(i=0;i<n;i++) //连续输入n个元素 { scanf("%d",&e); InsertBST(T,e); //插入元素 } printf("\n\t成功创建该二叉树!",n); c=getchar(); //用来吸收多余字符 c=getchar(); //用来吸收多余字符 } while(1) //进入程序的循环 { system("cls"); //实现清屏处理 printf(" ☆ 实现平衡二叉树的各种算法 ☆ \n"); printf(" \n"); printf(" ◆◆◆◆◆◆◆◆◆◆◆◆ 请从下面的操作中选择一项 ◆◆◆◆◆◆◆◆◆◆◆◆◆\n"); printf(" ◆ ◆\n"); printf(" ◆ ◆ 1.在二叉树中插入新结点 ◆\n"); printf(" ◆ ◆ 2.实现递归的前序、中序、后序遍历二叉树 ◆\n"); printf(" ◆ ◆ 3.实现非递归的前序、中序、后序遍历二叉树 ◆\n"); printf(" ◆ ◆ 4.实现层次遍历二叉树 ◆\n"); printf(" ◆ ◆ 5.在二叉树中查找给定关键字 ◆\n"); printf(" ◆ ◆ 6.交换二叉树中各结点的左右子树 ◆\n"); printf(" ◆ ◆ 7.实现二叉树的深度的求值 ◆\n"); printf(" ◆ ◆ 8.统计二叉树中叶子结点数 ◆\n"); printf(" ◆ ◆ 9.在二叉树中删除某结点 ◆\n"); printf(" ◆ ◆ 0.退出本程序 ◆\n"); printf(" ◆ ◆\n"); printf(" ◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆\n"); printf("\n\t你的选择是:"); scanf("%d",&ch); switch(ch) //进入选择 { case 1: //调用插入结点的函数 printf("\n\t请输入你想要插入的元素:"); scanf("%d",&e); if(InsertBST(T,e)==OK) printf("\n\t成功插入元素%d!\n",e); else printf("\n\t插入元素%d失败!\n",e); break; case 2: //调用打印各种递归遍历的函数 printf("\n\t平衡二叉树的各种递归遍历如下:\n"); AllOrderTraverse(T); break; case 3: //调用打印各种非递归遍历的函数 printf("\n\t平衡二叉树的各种非递归遍历如下:\n"); NonAllOrder(T,S); break; case 4: //调用打印层次遍历的函数 printf("\n\t平衡二叉树的层次遍历如下:\n\t"); CreatQueue(Q); //创建队列 LevelTraverse(T,Q); printf("\n"); break; case 5: //调用关键字查找的函数 printf("\n\t请输入你想要查找的关键字:"); scanf("%d",&k); if(PostsSearch(T,k)==OK) //返回查找的值,成功返回1,失败则返回0 printf("\n\t成功找到关键字%d!\n",k); else printf("\n\t没有找到关键字%d!\n",k); break; case 6: //调用转换子树的函数 if(SwapSubtree(T)==OK) printf("\n\t成功交换左右子树!\n"); else printf("\n\t交换左右子树失败!\n"); break; case 7: //调用求二叉树深度的函数 printf("\n\t平衡二叉树的深度是:"); printf("%d\n",TreeDepth(T)); break; case 8: //调用统计树结点数的函数 printf("\n\t平衡二叉树的总结点数是:"); printf("%d\n",TotalNodeNum(T)); printf("\n\t平衡二叉树的叶子结点数是:"); printf("%d\n",LeafNodeNum(T)); break; case 9: //调用删除结点的函数 printf("\n\t请输入你想要删除的元素:"); scanf("%d",&d); if(DeleteBST(T,d)==OK) printf("\n\t成功删除元素%d!\n",d); else printf("\n\t删除失败,没有找到元素%d!\n",d); break; case 0: //输入0,则推出本程序 return 0; break; default: //如果输入非法字符,则进入该分支 c=getchar(); //用来吸收多余字符 printf("\n\a\t输入错误,请重新输入!\n"); break; } scanf("%c",&c); //用来吸收多余字符 printf("\n\t按任意键继续,或按“n”退出!你的选择是:"); scanf("%c",&c); if(c=='n') return 0; } return 0; }
1 0
- AVL树C代码
- c语言版avl树代码下载
- AVL树及C实现代码
- AVL树的建立完整C代码
- 动态AVL树代码
- AVL树 实现代码
- AVL树实现代码
- AVL树代码
- AVL树 实现代码!
- AVL树C实现
- AVL树C实现
- AVL树C实现
- AVL树-C实现
- AVL树( C++)
- 【c++】AVL树详解
- 数据结构(C++)<AVL树>
- avl树 C实现
- AVL树的实现代码
- 系统集成项目管理工程师教程看书笔记13
- Object-C中的网络请求如何取出和设置cookie
- 线性表
- 快速幂计算
- 11-hive数据查询方式
- AVL树C代码
- C++模板实现二叉查找树(三 深度优先遍历)
- C++学习中的(。。。)问题
- 根据C语言制作九九乘法表
- Google Guava 使用Optional<T>
- 文件操作
- http://rejoy.iteye.com/blog/1627405
- Java基础学习笔记--多态
- 【EF操作】——多表联查的linq操作