二叉平衡查找树AvlTree(C实现)
二叉平衡查找树即是一棵树中所有节点的左右子树高度差不超过1的查找树
头文件——————————————————————————————
#ifndef _AVLTREE_H_
#define _AVLTREE_H_
#include <stdlib.h>
#include <iomanip>
#include <iostream> typedef struct AvlNode *Position;
typedef Position AvlTree;
#define Element int
struct AvlNode
{
Element data;
int height;//叶子节点高度定义为0,其父节点为1以此类推
AvlTree left;
AvlTree right;
}; static int Height(AvlTree avl);
void SwapAvlNode(Position *p1, Position *p2);
Position GetNotBalancedNode(AvlTree avl);
void MakeEmpty(AvlTree* pavl);
Position Find(Element x, AvlTree avl);
Position FindMin(AvlTree avl);
Position FindMax(AvlTree avl);
void Insert(Element x, AvlTree* pavl);
void Delete(Element x, AvlTree* pavl);
Element Retrieve(Position p);
void SingleRotateWithLeftLeft(Position *pK2);
void SingleRotateWithRightRight(Position *pK2);
void DoubleRotateWithLeftRight(Position *pK3);
void DoubleRotateWithRightLeft(Position *pK3);
void PrintTree(AvlTree avl, int Depth, int ctrl);
#endif
源文件————————————————————————————————
#include "./AvlTree.h" int Max(int a, int b)
{
if(a <= b)
return b;
return a;
}
void SwapAvlNode(Position *p1, Position *p2)
{
Position tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int Abs(int a)
{
if(a < 0) return -a;
return a;
}
static int Height(AvlTree avl)
{
if(NULL == avl)
return -1;
else
return avl->height;
}
Position GetNotBalancedNode(AvlTree avl)
{
if(NULL == avl)
return NULL;
else
{
if(Height(avl->left) - Height(avl->right) == Abs(2))//not balanced
return avl;
else
{
Position res = GetNotBalancedNode(avl->left);
if(NULL != res)//avl->left is not balanced
return res;
else
return GetNotBalancedNode(avl->right);
}
}
}
void MakeEmpty(AvlTree* pavl)
{
if(NULL != (*pavl))
{
MakeEmpty(&((*pavl)->left));
MakeEmpty(&((*pavl)->right));
free(*pavl);
*pavl = NULL;
}
}
Position Find(Element x, AvlTree avl)
{
Position pos = avl;
while(NULL != pos)
{
if(x < Retrieve(pos))
pos = pos->left;
else if(x > Retrieve(pos))
pos = pos->right;
else
break;
}
return pos;
}
Position FindMin(AvlTree avl)
{
while(NULL != avl && NULL != avl->left)
avl = avl->left;
return avl;
}
Position FindMax(AvlTree avl)
{
while(NULL != avl && NULL != avl->right)
avl = avl->right;
return avl;
}
void Insert(Element x, AvlTree* pavl)
{
if(NULL == (*pavl))
{
Position tmp = (Position)malloc(sizeof(struct AvlNode));
if(NULL == tmp)
return ;
tmp->data = x;
tmp->height = 0;
tmp->left = tmp->right = NULL;
*pavl = tmp;
}
else
{
if(x < Retrieve(*pavl))//在*pavl的左儿子上插入
{
Insert(x, &((*pavl)->left));
if(Height((*pavl)->left) - Height((*pavl)->right) == 2)//不平衡
{
if(x < Retrieve((*pavl)->left))//左儿子的左子树
SingleRotateWithLeftLeft(pavl);
else//左儿子的右子树
DoubleRotateWithLeftRight(pavl);
}
}
else if(x > Retrieve(*pavl))//在*pavl的右儿子上插入
{
Insert(x, &((*pavl)->right));
if(Height((*pavl)->right) - Height((*pavl)->left) == 2)//不平衡
{
if(x > Retrieve((*pavl)->right))//右儿子的右子树
SingleRotateWithRightRight(pavl);
else//右儿子的左子树
DoubleRotateWithRightLeft(pavl);
}
}
}
(*pavl)->height = Max(Height((*pavl)->left), Height((*pavl)->right)) + 1;
}
void Delete(Element x, AvlTree* pavl)
{
if(NULL == *pavl)
return ;
if(x < Retrieve((*pavl)))//go left
Delete(x, &((*pavl)->left));
else if(x > Retrieve((*pavl)))//go right
Delete(x, &((*pavl)->right));
else if(NULL != (*pavl)->left && NULL != (*pavl)->right)//*pavl has two children
{
//利用右子树的最小值tmp->data来替代被删除的节点上的值x,然后在右子树上递归的删除值tmp->data
Position tmp = FindMin((*pavl)->right);
(*pavl)->data = tmp->data;
Delete(tmp->data, &((*pavl)->right));
}
else//*pavl has none or one child
{
Position tmp = *pavl;
if(NULL == (*pavl)->left)//*pavl has right child
*pavl = (*pavl)->right;
else if(NULL == (*pavl)->right)//*pavl has left child
*pavl = (*pavl)->left;
free(tmp);
}
if(NULL != *pavl)//最后更新*pavl节点上的高度
{
(*pavl)->height = Max(Height((*pavl)->left), Height((*pavl)->right)) + 1;
if(2 == Height((*pavl)->left) - Height((*pavl)->right))//not balanced
{
if(NULL == (*pavl)->left->right)
SingleRotateWithLeftLeft(pavl);
else
DoubleRotateWithLeftRight(pavl);
}
else if(2 == Height((*pavl)->right) - Height((*pavl)->left))//not balance
{
if(NULL == (*pavl)->right->left)
SingleRotateWithRightRight(pavl);
else
DoubleRotateWithRightLeft(pavl);
}
}
}
Element Retrieve(Position p)
{
return p->data;
}
void SingleRotateWithLeftLeft(Position *pK2)
{
Position k2 = *pK2;
Position k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k1->height = Max(Height(k1->left), Height(k2)) + 1;
k2->height = Max(Height(k2->left), Height(k2->right)) + 1;
*pK2 = k1;
}
void SingleRotateWithRightRight(Position *pK2)
{
Position k2 = *pK2;
Position k1 = k2->right;
k2->right = k1->left;
k1->left = k2;
k1->height = Max(Height(k2), Height(k1->right)) + 1;
k2->height = Max(Height(k2->left), Height(k2->right)) + 1;
*pK2 = k1;
}
void DoubleRotateWithLeftRight(Position *pK3)
{
SingleRotateWithRightRight(&((*pK3)->left));
SingleRotateWithLeftLeft(pK3);
}
void DoubleRotateWithRightLeft(Position *pK3)
{
SingleRotateWithLeftLeft(&((*pK3)->right));
SingleRotateWithRightRight(pK3);
}
void PrintTree(AvlTree avl, int Depth, int ctrl)//ctrl:0=root 1=left 2=right
{ if(NULL != avl)
{
std::cout<<std::setw(Depth);
if(0 == ctrl)
std::cout<<"rt:";
else if(1 == ctrl)
std::cout<<"l";
else if(2 == ctrl)
std::cout<<"r";
std::cout<<avl->data<<std::endl;
PrintTree(avl->left, Depth+3, 1);
PrintTree(avl->right, Depth+3, 2);
}
}
二叉平衡查找树AvlTree(C实现)的更多相关文章
- 数据结构:JAVA_二叉数查找树基本实现(中)
数据结构:二叉数查找树基本实现(JAVA语言版) 1.写在前面 二叉查找树得以广泛应用的一个重要原因是它能保持键的有序性,因此我们可以把它作为实现有序符号表API中的众多方法的基础. 也就是说我们构建 ...
- 数据结构:JAVA_二叉数查找树基本实现(上)
数据结构:二叉数查找树基本实现(JAVA语言版) 1.写在前面 二叉查找树是一种能将链表插入的灵活性与有序数组查找的高效性结合在一起的一种数据结构. ..... 2.代码分解 2.1 对节点的结构定义 ...
- 树-二叉搜索树-AVL树
树-二叉搜索树-AVL树 树 树的基本概念 节点的度:节点的儿子数 树的度:Max{节点的度} 节点的高度:节点到各叶节点的最大路径长度 树的高度:根节点的高度 节点的深度(层数):根节点到该节点的路 ...
- 浅谈算法和数据结构: 七 二叉查找树 八 平衡查找树之2-3树 九 平衡查找树之红黑树 十 平衡查找树之B树
http://www.cnblogs.com/yangecnu/p/Introduce-Binary-Search-Tree.html 前文介绍了符号表的两种实现,无序链表和有序数组,无序链表在插入的 ...
- 剑指offer-第四章解决面试题思路(二叉收索树和双向链表)
题目:输入一个二叉收索树,将二叉搜索树转换成排序的双向链表.要求不能创建节点,只能将链表中的指针进行改变. 将复杂的问题简单化:思路:二叉收索树,本身是一个排序结构,中序遍历二叉收索树就可以得到一组排 ...
- 高度平衡的二叉搜索树(AVL树)
AVL树的基本概念 AVL树是一种高度平衡的(height balanced)二叉搜索树:对每一个结点x,x的左子树与右子树的高度差(平衡因子)至多为1. 有人也许要问:为什么要有AVL树呢?它有什么 ...
- 数据结构-查找-二叉排序查找(平衡二叉树,B树,B+树概念)
0.为什么需要二叉排序树 1)数组存储方式: 优点:通过下标访问元素,速度快,对于有序数组,可以通过二分查找提高检索效率: 缺点:如果检索具体某个值,或者插入值(按一定顺序)会整体移动,效率较低: 2 ...
- (4) 二叉平衡树, AVL树
1.为什么要有平衡二叉树? 上一节我们讲了一般的二叉查找树, 其期望深度为O(log2n), 其各操作的时间复杂度O(log2n)同时也是由此决定的.但是在某些情况下(如在插入的序列是有序的时候), ...
- 浅谈算法和数据结构: 十 平衡查找树之B树
前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种 ...
随机推荐
- Factory模式
使用new的Code都违反了DIP. 但是,依赖于稳定的具体类,是无害的.例如string. 另一方面,对于正在开发中的APP,很多具体类是易变的.此时应该依赖于抽象接口. Factory模式:只依赖 ...
- Windows Server 安装 BitLocker
打开PowerShell(管理员): C:\> Install-WindowsFeature BitLocker -Restart 安装好后,系统会自动重新启动. Windows Server ...
- ZZmsvcprt.lib(MSVCP90.dll) : error LNK2005:已经在libcpmtd.lib(xmutex.obj) 中定义 .的分析解决办法 (转)
很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) 连结,以及关于 MSVC 与 CRT 之间的种种恩怨情仇. 如果你使用的作业系统是 Linux.Mac 或其他非 W ...
- 搭建windows的solr6服务器(二)
首先搭建solr环境,如:solr6.0学习(一)环境搭建 修改各种配置文件. 1.修改solrhome下的solr.xml文件 注解掉zookeeper搭建集群配置,我们后面会采用master-sl ...
- jinkins在windows上的安装 配置C#编译
首先jinkins在windows上的安装就不说,安装只需要下载相应安装包就可以了,后有些时候经常需要修改端口号.修改如下: 然后重启jenkins服务 首次运行界面 个人建议插件按需安装. 建立一个 ...
- php生成UUID
UUID含义是 通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, O ...
- latextools \cite 自动补全
最近在用latex写毕业论文,编辑环境用的是Sublime Text 2 加 latextools 插件,在使用latextools的\cite命令来引用参考文献时,我们希望输入\cite{ 后自动弹 ...
- 从零开始--系统深入学习IOS(使用Swift---带链接)
这是一篇面向IOS新手的文档.同时提供一些系统知识的链接,让你系统学习IOS.它提供一些信息帮助你采用技术和编程接口来开发苹果软件产品,本人不保证会在将来更新.学习它,需要你掌握一些基本的编程知识 1 ...
- 微信公众平台开发视频教程-03-获取Access Token和获取微信服务器IP,添加微信菜单
1 获取access token 此token是以后每次调用微信接口都会带上的票据,token是公众号全局唯一票据,在调用其他接口之前都需要先得到token,taoken长度至少512个字符,通常用s ...
- Xshell中文乱码问题
1. 先查看当前使用的语言: echo $LANG 2. 查看系统的语言安装包: locale 3. 如果没有中文安装包(包含zh_CN字样),需要网络或者自己上传安装包,安装 4. 有了中文 ...