导航:首页 > 编程语言 > java平衡树判断

java平衡树判断

发布时间:2022-09-10 11:40:09

Ⅰ 数据结构:二叉排序树和平衡二叉树的判别

平衡二叉树(AVL)

那对图 1 进行下改造,把数据重新节点重新连接下,图 2 如下:

图 3 是一棵高度为 4 的 AVL 树,有 5 层共 31 个节点,橙色是 ROOT 节点,蓝色是叶子节点。对 AVL 树的查找来看起来已经很完美了,能不能再优化下?比如,能否把这个节点里存放的 KEY 增加?能否减少树的总层数?那减少纵深只能从横向来想办法,这时候可以考虑用多叉树。

Ⅱ 数据结构 平衡二叉树的操作演示

平衡二叉树(AVL)

那对图 1 进行下改造,把数据重新节点重新连接下,图 2 如下:

图 3 是一棵高度为 4 的 AVL 树,有 5 层共 31 个节点,橙色是 ROOT 节点,蓝色是叶子节点。对 AVL 树的查找来看起来已经很完美了,能不能再优化下?比如,能否把这个节点里存放的 KEY 增加?能否减少树的总层数?那减少纵深只能从横向来想办法,这时候可以考虑用多叉树。

Ⅲ 平衡二叉树是什么

平衡二叉树(AVL)

那对图 1 进行下改造,把数据重新节点重新连接下,图 2 如下:

图 3 是一棵高度为 4 的 AVL 树,有 5 层共 31 个节点,橙色是 ROOT 节点,蓝色是叶子节点。对 AVL 树的查找来看起来已经很完美了,能不能再优化下?比如,能否把这个节点里存放的 KEY 增加?能否减少树的总层数?那减少纵深只能从横向来想办法,这时候可以考虑用多叉树。

Ⅳ 如何判断一棵二叉树是否是平衡二叉树

平衡二叉树是指一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树,即所有结点,其左右子树高度差不超过1。
判读步骤是:
先计算所有结点的高度,高度是从叶节点开始(其高度为1)自底向上逐层累加的,不同叶子节点计算开始计算时,高度不同取最大值。
然后计算结点左右子树的高度差,如果绝对值都不超过1,就是平衡的。
例子:
A
/ \
B C
/ \
D E
高度是 D:1 E:1 B:2 C:1 A:3,A的高度差为1, B为0 C为0 叶子结点可以不用计算,肯定为0。上述例子的二叉树就是平衡的二叉树。
看一下例子
A
/ \
B C
/ \
D E
/
F
高度是 F:1 D:2 E:1 B:3 C:1 A:4,其中A的左右子树高度差B3 - A1 = 2,高度差大于2,所以不平衡。
当然实际判断是不是平衡二叉树,不一定需要计算每一个结点高度,因为左子树高一点或者右子树高一点,表面看过去还是比较明显的,计算一下比较明显的几个点就可以。

Ⅳ 急!急!急!用java实现:二叉平衡树的插入和删除

另一道题的 给你放这里了 呵呵
没找到邮箱
package Test;

import java.util.Random;
import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class Bai {
/**
* 生成随机数组
* @param n int
* @return int[]
*/
public int[] creatarray(int n) {

Random random = new Random();
int array[] = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = random.nextInt();
}
return array;
}

/**
* 排序函数
* @param data int[]
* @param n 参数长度
* @param cNo 比较的值 是0
*/
public int[] merge(int[] data, int n, int cNo) {
int length1 = 0;
int length2 = 0;
int length0 = 0;
int array1[] = new int[n]; //正数
int array2[] = new int[n]; //负数
int array0[] = new int[n]; //零
int redata[] = new int[n]; //返回数组
for (int i = 0; i < n; i++) {
if (data[i] > 0) {
array1[length1] = data[i];
length1++;
} else if (data[i] == 0) {
array0[length0] = data[i];
length0++;
} else {
array2[length2] = data[i];
length2++;
}
}
for (int i = 0; i < length1; i++) {
redata[i] = array1[i];
}
for (int i = 0; i < length0; i++) {
redata[length1 + i] = array0[i];
}
for (int i = 0; i < length2; i++) {
redata[length1 + length0 + i] = array2[i];
}
// for (int i = 0; i < n; i++) {
// System.out.println(data[i] + " " + redata[i]);
// }
return redata;
}

/**
* 输出函数
* @param time int[]
* @param before int[]
* @param end int[]
* @param n int
*/
public void out(long[] time, int[] before, int[] end, int n) {
for (int v = 0; v < n; v++) {
System.out.println("第" + v + "组耗时:" + time[v] );
}
}

public static void main(String args[]) {
Bai tt = new Bai();
// Calendar cCalendar1 = Calendar.getInstance();
// long currTimebegin = cCalendar1.getTimeInMillis();
int[] array = new int[20];
int[] arrayEnd = new int[20];
int forNum = 3; //循环次数
long[] timeall = new long[forNum];
for (int i = 0; i < forNum; i++) {
array = tt.creatarray(100);
long currTimebegin = System.currentTimeMillis();
arrayEnd = tt.merge(array, 20, 0);
long currTimeend = System.currentTimeMillis();
long time = currTimeend - currTimebegin;
timeall[i] = time;
System.out.println(currTimeend + "-" + currTimebegin + "=" + time);
}
tt.out(timeall, array, arrayEnd, forNum);
}
}
可以用了 可是耗时都是在毫秒级别以下的 就是运行一次排序还不到1毫秒
我debug时看到每次时间确实可以取到 时间差也能算出来

Ⅵ 用Java怎么实现平衡树动态演示

publicclasstreenode1{//二叉树的结点类
publicstringdata;//数据元数
publictreenode1left,right;//指向左,右孩子结点的链

publictreenode1(){
this("?");
}

publictreenode1(stringd){//构造有值结点
data=d;
left=right=null;
}

publicvoidpreorder(treenode1p){//先根次序遍历二叉树
if(p!=null){
system.out.print(p.data+"");
preorder(p.left);
preorder(p.right);
}
}

publicvoidinorder(treenode1p){//中根次序遍历二叉树
if(p!=null){inorder(p.left);
system.out.print(p.data+"");
inorder(p.right);
}
}

publicvoidpostorder(treenode1p){//后根次序遍历二叉树
if(p!=null){postorder(p.left);
postorder(p.right);
system.out.print(p.data+"");
}
}
}

Ⅶ 平衡树的主要算法

红黑树的平衡是在插入和删除的过程中取得的。对一个要插入的数据项,插入程序要检查不会破坏树一定的特征。如果破坏了,程序就会进行纠正,根据需要更改树的结构。通过维持树的特征,保持了树的平衡。
红黑树有两个特征:
(1) 节点都有颜色
(2) 在插入和删除过程中,要遵循保持这些颜色的不同排列的规则。
红黑规则:
1. 每一个节点不是红色的就是黑色的
2. 根总是黑色的
3. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定成立)
4. 从根到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点。
(空子节点是指非叶节点可以接子节点的位置。换句话说,就是一个有右子节点的节点可能接左子节点的位置,或是有左子节点的节点可能接右子节点的位置) AVL树,它或者是一颗空二叉树,或者是具有下列性质的二叉树:
(1) 其根的左右子树高度之差的绝对值不能超过1;
(2) 其根的左右子树都是二叉平衡树。
AVL树查找的时间复杂度为O(logN),因为树一定是平衡的。但是由于插入或删除一个节点时需要扫描两趟树,依次向下查找插入点,依次向上平衡树,AVL树不如红黑树效率高,也不如红黑树常用。
AVL树插入的C++代码: template<classT>ResultCodeAVLTree<T>::Insert(AVLNode<T>*&p,T&x,bool&unBalanced)...{ResultCoderesult=Success;if(p==null)...{//插入新节点p=newAVLNode<T>(x);unBalanced=true;}elseif(x<p->element)...{//新节点插入左子树result=Insert(p->lChild,x,unBalanced);if(unBanlanced)...{switch(p->bF)...{case-1:p->bF=0;unBalanced=false;break;case0:p->bF=1;break;case1:LRotation(p,unBalanced);}}}elseif(x==p->element)...{//有重复元素,插入失败unBalanced=false;x=p->element;result=Duplicate;}else...{//新节点插入右子树result=Insert(p->rChild,x,unBalanced);if(unBalanced)...{switch(p->bF)...{case1:p->bF=0;unBalanced=false;break;case0:p->bF=-1;break;case-1:RRotation(p,unBalanced);}}}returnresult;}template<classT>voidAVLTree<T>::LRotation(AVLNode<T>*&s,bool&unBalanced)...{AVLNode<T>*u,*r=s->lChild;if(r->bF==1)...{//LL旋转s->lChild=r->rChild;r->rChild=s;s->bF=0;s=r;//s指示新子树的根}else...{//LR旋转u=r->rChild;r->rChild=u->lChild;u->lChild=r;s->lChild=u->rChild;u->rChild=s;switch(u->bF)...{case1:s->bF=-1;r->bF=0;break;case0:s->bF=r->bF=0;break;case-1:s->bF=0;r->bF=1;}s=u;//s指示新子树的根}s->bF=0;//s的平衡因子为0unBalanced=false;//结束重新平衡操作}通常我们使用二叉树的原因是它可以用O(logn)的复杂度来查找一个数,删除一个数,对吧??可是有时候会发现树会退化,这个就可能使O(logn)->O(n)的了,那么还不如用直接搜一次呢!!所以我们就要想办法使一棵树平衡。而我仅仅看了(AVL)的那个,所以也仅仅能说(AVL)的那个,至于(TREAP),我还不懂,如果你们知道算法的话,欢迎告诉我~!谢谢~
首先引入一个变量,叫做平衡因子(r),节点X的r就表示x的左子树的深度-右子树的深度。然后我们要保证一棵树平衡,就是要保证左右子树的深度差小于等于1.所以r的取值能且仅能取0,-1,1.
其次,我要介绍旋转,旋转有两种方式,就是左旋(顺时针旋转)和右旋(逆时针旋转)。
左旋(左儿子代替根):即用左儿子取代根,假设我们要旋转以X为根,LR分别为X的左右儿子,那么我们只需要把L的右儿子取代X的左儿子,然后把更新后的X赋值为L的右儿子,就可以了。
右旋(右儿子代替根):即用右儿子取代根,假设我们要旋转以X为根,LR分别为X的左右儿子,那么我们只需要把R的左儿子取代X的右儿子,然后把更新后的X赋值为R的左儿子,就可以了。 Size Balanced Tree(SBT平衡树)是2007年Winter Camp上由我国着名OI选手陈启峰发布的他自己创造的数据结构。相比于一般的平衡树,此平衡树具有的特点是:快速(远超Treap,超过AVL)、代码简洁、空间小(是线段树的1/4左右)、便于调试和修改等优势。
与一般平衡搜索树相比,该数据结构只靠维护一个Size来保持树的平衡,通过核心操作Maintain(修复)使得树的修改平摊时间为O(1)。因而大大简化代码实现复杂度、提高运算速度。
参见网络SBT。 平衡树的一种,每次将待操作节点提到根,每次操作时间复杂度为O(logn)。见伸展树。 constintSPLAYmaxn=200005;constintSPLAYinf=100000000;structSplay_Node{intl,r,fa,v,sum;};structSplay{Splay_Nodet[SPLAYmaxn];introot,tot;voidcreate(){root=1,tot=2;t[1].v=-SPLAYinf;t[2].v=SPLAYinf;t[1].r=t[1].sum=2;t[2].fa=t[2].sum=1;}voipdate(intnow){t[now].sum=t[t[now].l].sum+t[t[now].r].sum+1;}voidleft(intnow){intfa=t[now].fa;t[now].fa=t[fa].fa;if(t[t[fa].fa].l==fa)t[t[fa].fa].l=now;if(t[t[fa].fa].r==fa)t[t[fa].fa].r=now;t[fa].fa=now;t[fa].r=t[now].l;t[t[now].l].fa=fa;t[now].l=fa;up(fa);}voidright(intnow){intfa=t[now].fa;t[now].fa=t[fa].fa;if(t[t[fa].fa].l==fa)t[t[fa].fa].l=now;if(t[t[fa].fa].r==fa)t[t[fa].fa].r=now;t[fa].fa=now;t[fa].l=t[now].r;t[t[now].r].fa=fa;t[now].r=fa;update(fa);}voidsplay(intnow,intFA=0){while(t[now].fa!=FA){intfa=t[now].fa;if(t[fa].fa==FA)if(t[fa].l==now)right(now);elseleft(now);elseif(t[t[fa].fa].l==fa)if(t[fa].l==now)right(fa),right(now);elseleft(now),right(now);elseif(t[fa].l==now)right(now),left(now);elseleft(fa),left(now);}update(now);if(!FA)root=now;}intlower_bound(intv){intans=0,la=0;for(intnow=root;now;){la=now;if(t[now].v>=v)ans=now,now=t[now].l;elsenow=t[now].r;}splay(la);returnans;}voidinsert(intv){for(intnow=root;;){++t[now].sum;if(t[now].v>=v)if(t[now].l)now=t[now].l;else{t[now].l=++tot;t[tot].sum=1;t[tot].fa=now;t[tot].v=v;splay(tot);return;}elseif(t[now].r)now=t[now].r;else{t[now].r=++tot;t[tot].sum=1;t[tot].fa=now;t[tot].v=v;splay(tot);return;}}}intget_lower(inta){splay(a);for(a=t[a].l;t[a].r;a=t[a].r);returna;}intget_upper(inta){splay(a);for(a=t[a].r;t[a].l;a=t[a].l);returna;}intget_rank(inta){splay(a);returnt[t[a].l].sum;}voiddel(intl,intr){l=get_lower(l);r=get_upper(r);splay(l);splay(r,l);t[r].l=0;update(r);update(l);}intget_kth(intk){++k;for(intnow=root;;){if(t[t[now].l].sum==k-1)returnnow;if(t[t[now].l].sum>=k)now=t[now].l;elsek-=t[t[now].l].sum+1,now=t[now].r;}}};

Ⅷ 什么是平衡二叉树

平衡二叉树,又称AVL树。它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的高度之差之差的绝对值不超过1.。

常用算法有:红黑树、AVL树、Treap等。

平衡二叉树的调整方法

平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。具体步骤如下:
⑴ 每当插入一个新结点,从该结点开始向上计算各结点的平衡因子,即计算该结点的祖先结点的平衡因子,若该结点的祖先结点的平衡因子的绝对值均不超过1,则平衡二叉树没有失去平衡,继续插入结点;
⑵ 若插入结点的某祖先结点的平衡因子的绝对值大于1,则找出其中最小不平衡子树的根结点;
⑶ 判断新插入的结点与最小不平衡子树的根结点的关系,确定是哪种类型的调整;
⑷ 如果是LL型或RR型,只需应用扁担原理旋转一次,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;如果是LR型或LR型,则需应用扁担原理旋转两次,第一次最小不平衡子树的根结点先不动,调整插入结点所在子树,第二次再调整最小不平衡子树,在旋转过程中,如果出现冲突,应用旋转优先原则调整冲突;
⑸ 计算调整后的平衡二叉树中各结点的平衡因子,检验是否因为旋转而破坏其他结点的平衡因子,以及调整后的平衡二叉树中是否存在平衡因子大于1的结点。

阅读全文

与java平衡树判断相关的资料

热点内容
dos选择命令 浏览:16
apm固件编译到单片机 浏览:120
联通深蓝卡都包含什么app 浏览:263
如何判断网络服务器正常 浏览:649
路由器搭桥远端服务器地址是什么 浏览:515
编译动态库时会连接依赖库吗 浏览:707
淘宝手机加密是随机的吗 浏览:672
解压包子怎么装饰 浏览:585
四个数凑24算法 浏览:676
哪一种不是vi编译器的模式 浏览:169
xp在此处打开命令窗口 浏览:128
代码编译运行用什么软件 浏览:998
动态库在程序编译时会被连接到 浏览:761
python超简单编程 浏览:259
获取命令方 浏览:977
怎样制作文件夹和图片 浏览:60
调研编译写信息 浏览:861
python冯诺依曼 浏览:419
同时安装多个app有什么影响 浏览:254
奥术杀戮命令宏 浏览:184