
正文
平衡二叉树代码java 平衡二叉树程序
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
跪求平衡二叉树pascal代码。怎么办?
"AVL树插入算法平衡二叉树代码java的基本步骤如下:
①在寻找新结点平衡二叉树代码java的插入位置的过程中平衡二叉树代码java,记下离该位置近来、且平衡因子不等于零的结点a(此结点即为可能出现的最小失衡子树的根)平衡二叉树代码java;
②修改自该结点至插入位置路径上全部结点的平衡因子(注意:树上其它结点的平衡因子均不受插入的影响);
③判别实施插入操作之后,结点a的平衡因子的绝对值是不是大于1(即判别是不是失衡)。若是,进一步判别失衡类型并做相应调整;否则插入过程结束。
仍以二叉链表作为AVL树的存储结构。但每一个结点需增加1个域用于存储平衡因
子。类型定义如下:
type
avlpt=^anode;
anode=record
key:keytype;
bf:-1..1;
lchild,rchild:avlpt;
...
end;
在此存储结构上,AVL树的插入算法如下:
procedure
insert_avltree(K:keytype;var
t:avlpt);
//在以T为根指针的AVL树上插入键值等于K的新结点//
begin
new(s);s^.key:=K;s^.lchild:=nil;s^.lchild:=nil;//生成以K为键值的新结点//
if
t=nil
then
t:=s
//将新结点作为根结点插入空树//
else
begin
//4-10行:查找S^的插入位置,并记录a//
f:=nil;a:=t;p:=t;q:=nil;
while
pnil
do
[
if
p^.bf0
then
[a:=p;f:=p];
//a记录bf0的结点,其终值指向离插入位置近来的bf0的结点//
q:=p;
//s^将插到q^上//
if
s^.keyp^.key
then
p:=p^.lchild
else
p:=p^.rchild
];
if
s^.keyq^.key
then
q^.lchild:=s
else
q^.rchild:=s;
//插入s^//
if
s^.keya^.key
then
[
p:=a^.lchild;b:=p;
d:=1
]
//s^插在a^的左子树上,增量D为1//
else
[
p:=a^.rchild;b:=p;d:=-1
];//s^插在A^的右子树上,增量D为-1//
while
ps
do
//修改自a^的孩子至S^路径上各结点的平衡因子//
if
s^.keyp^.key
//若S^在p^的左子树上//
then
[
p^.bf:=1;p:=p^.lchild
]
//p^的平衡因子加工1—原来为O,由于p^是a^的子孙//
else
[p^.bf:=-1;p:=p^.lchild];
//p^的平衡因子减1—原来为0//
case
//判别是不是失衡//
a^.bf=0:
a^.bf:=d;
//找插入位置过程中未遇到bf0的结点,A指根树//
a^.bf+d=0:
a^.bf:=0
//插入不导致以a^为根的子树失衡//
else
//其它情形均失衡。差别失衡类型并调整//
[
if
d=1
then
case
b^.bf=1:LL-rotation;//LL型调整//
b^.bf=-1:LR-rotation//LR型调整,结束时令B指新子树的根//
end;
else
case
b^.bf=-1:RR-rotation;
b^.bf=1:RL-rotation
//结束时令b指新子树的根//
end;
case
//将新子树链接到原a^的双亲f^上//
f=nil:t:=b;//原a^为树根//
f^.lchild=a:f^.lchild:=b;
f^.rchild=a:f^.rchild:=b
end
]
end
end;
二叉排序树(包括AVL树)适合于组织较小的、内存中能容纳的查找表。若查找表大得必须存放在外部存储器上,再用二叉排序树来表示就不合适了。对外存文件的组织来说,需考虑采用其他的数据结构(如B树和B+树)。"
相关问答
Q1: 平衡二叉树的操作(高手进)
以前做的。
一、 需求分析
1. 本程序是是利用平衡二叉树实现一个动态查找表,实现动态查找表的三种基本功能:查找、插入和删除。
2. 初始,平衡二叉树为空树,可以按先序输入平衡二叉树,以输入0结束,中间以回车隔开,创建好二叉树后,可以对其查找,再对其插入,输入0结束插入,再可以对其删除,输入0结束,每次插入或删除一个结点后,更新平衡二叉树的显示。
3. 本程序以用户和计算机的对话方式执行,根据计算机终端显示:“提示信息”下,用户可由键盘输入要执行的操作。
4. 测试数据(附后)
二、 概要设计
1. 抽象数据类型动态查找表的定义如下:
ADT DynamicSearchTable{
数据结构D:D是具有相同特性的数据元素的集合。各个数据元素含有类型相同,可惟一标识数据元素的关键字。
数据关系R:数据元素同属一个集合。
基本操作P:
InitDSTable(DT);
操作结果:构造一个空的动态查找表DT。
DestroyDSTable(DT);
初试条件:动态查找表DT存在。
操作结果: 销毁动态查找表DT。
SearchDSTable(DT,key);
初试条件:动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果: 若DT中存在其关键字等于key的数据元素,则函数值为该元素的值或表中的位置,否则为“空”。
InsertDSTable(DT,e);
初试条件:动态查找表DT存在,e为待插入的数据元素。
操作结果: 若DT中不存在其关键字等于e. key的数据元素,则插入e到DT。
DeleteDSTable(DT,key);
初试条件:动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果: 若DT中存在其关键字等于key的数据元素,则删除之。
TraverseDSTable(DT,Visit());
初试条件:动态查找表DT存在,Visit()是结点操作的应用函数。
操作结果: 按某种次序对DT的每个结点调用函数Visit()一次且至多
一次。一但Visit()失败,则操作失败。
}ADT DynamicSearchTable
2. 本程序包含两个模块:
Void main(){
Do{
接受命令(根据提示输入终点城市和起点城市的序号);
处理命令;
}while(“命令”=“退出”);
}
3.本程序只有两个模块,调用关系简单
主程序模块
平衡二叉树的模块
三、 详细设计
1. 根据题目要求和查找的基本特点,其结点类型
typedef struct BSTnode{
int data;
int bf;
struct BSTnode *lchild,*rchild;
}BSTnode,*bstree;
#define LH +1
#define EH 0
#define RH -1
/-----------------------------************对平衡二叉树的操作
bstree InsertAVL(bstree T, int e);
////////在平衡二叉树中插入结点。
int FindAVL(bstree p,int e);
////////查找平衡二叉树中是否有结点e。
bstree DeleteAVL(bstree T,int e)
////////删除平衡平衡二叉树的结点e,并保持平衡二叉树的性质。
int Preordertraverse(bstree T)
////////按先序遍历平衡二叉树。
/------------------------************平衡二叉树的操作的详细算法
bstree InsertAVL(bstree T, int e)
{
bstree p;
//插入新结点,树长高置taller为TRUE
if(!T) {
T=(bstree)malloc(sizeof(BSTnode));
T-data=e;
T-lchild=T-rchild=NULL;
T-bf=EH;
taller=TRUE;
}
else {
//树中存在和e有相同关键字的结点则不再插入
if(e==T-data){
taller=FALSE;
return NULL;
}
//值小于则继续在树的左子树中搜索
if(e T-data){
//插入到左子树且左子树长高
p=InsertAVL(T-lchild,e);
if(p){
T-lchild=p;
if(taller) {
switch(T-bf){ //检查*T的平衡度
case LH: //原本左子树比右子树高,需要做左平衡处理
T=LeftBalance(T);
taller=FALSE;
break;
case EH: //原本左子树和右子树同高,现因左子树争高而使树增高
T-bf=LH;
taller=TRUE;
break;
case RH: //原本右子树比左子树高,现在左右子树等高
T-bf=EH;
taller=FALSE;
break;
}///////switch(T-bf)
}///////if(taller)
}/////if(p)
}///////if(e T-data)
//继续在*T的右子树中搜索
else{
//插入到右子树且使右子树长高
p=InsertAVL(T-rchild,e);
if (p){
T-rchild=p;
if(taller) {
switch(T-bf){ //检查*T的平衡度
case LH: //原本左子树比右子树高,现在左右子树等高
T-bf=EH;
taller=FALSE;
break;
case EH: //原本左子树和右子树同高,现因右子树增高而使树增高
T-bf=RH;
taller=TRUE;
break;
case RH: //原本右子树比左子树高,需要做右平衡处理
T=RightBalance(T);
taller=FALSE;
break;
}//////switch(T-bf)
}/////if(taller)
}/////if (p)
}//////if(e T-data)
}///////else
return T;
}
int Preordertraverse(bstree T){
if(T){
printf(" %d %d\n",T-data,T-bf);
Preordertraverse(T-lchild);
Preordertraverse(T-rchild);
}
return 1;
}
int FindAVL(bstree p,int e){
if(p==NULL)return NULL;
else if(e==p-data) return true;
else if(ep-data){
p=p-lchild;
return FindAVL(p, e);
}////左子树上查找
else {
p=p-rchild;
return FindAVL( p, e);
}////右子树上查找
}
bstree DeleteAVL(bstree T,int e){
//删除后要保证该二叉树还是平衡的
int n,m=0;/////标记
bstree q;
if(!T)return NULL;
else {
if(e==T-data) {////直接删除
n=Delete(T,e);
m=n;
if(m!=0) {
q=T;
DeleteAVL(T,m);
q-data=m;}
}
else {
if(eT-data){////在左子树上寻找
DeleteAVL(T-lchild,e);
if(shorter){
switch(T-bf){
case LH:T-bf=EH;shorter=true;break;
case EH:T-bf=RH;shorter=false;break;
case RH:Delete_Rightbalance(T);shorter=true;break;
}////switch(T-bf)
}/////if(shorter)
}/////if(eT-data)
else{ /////////在右子树上寻找
DeleteAVL(T-rchild,e);
if(shorter)
switch(T-bf){
case LH:Delete_Leftbalance(T);shorter=true;break;
case EH:T-bf=LH;shorter=false;break;
case RH:T-bf=EH;shorter=true;break;
}////////switch(T-bf)
}////////在右子数上寻找完
}////////在左右子上完
}///////////删除完
return T;
}
2. 主程序和其他伪码算法
void main(){
while(e!=0){
if(e!=0) InsertAVL(T,e);
}
while(d!=0){
if(d!=0) InsertAVL(T,d);
Preordertraverse(T);
}
c=FindAVL(T,t);
if(c==1)printf("有要查找的节点\n");
else printf("无要查找的节点\n");
do{
DeleteAVL(T,b);
Preordertraverse(T);
}while(b==1);
}
///右旋
bstree R_Rotate(bstree p){
bstree lc;
lc=p-lchild;
p-lchild=lc-rchild;
lc-rchild=p;
p=lc;
return p;
}
////左旋
bstree L_Rotate(bstree p){
bstree rc;
rc=p-rchild;
p-rchild=rc-lchild;
rc-lchild=p;
p=rc;
return p;
}
/////左平衡处理
bstree LeftBalance(bstree T){
bstree lc,rd;
lc=T-lchild; //lc指向*T的左子树根结点
switch(lc-bf) { //检查*T的左子树平衡度,并做相应的平衡处理
case LH: //新结点插入在*T的左孩子的左子树上,要做单右旋处理
T-bf=lc-bf=EH;
T=R_Rotate(T);
break;
case RH: //新结点插入在*T的左孩子的右子树上,要做双旋处理
rd=lc-rchild; //rd指向*T的左孩子的右子树根
switch(rd-bf){ //修改*T及其左孩子的平衡因子
case LH:
T-bf=RH;
lc-bf=EH;
break;
case EH:
T-bf=lc-bf=EH;
break;
case RH:
T-bf=EH;
lc-bf=LH;
break;
}//////////switch(rd-bf)
rd-bf=EH;
T-lchild=L_Rotate(T-lchild); //对*T的左孩子做左旋平衡处理
T=R_Rotate(T); //对*T做右旋处理
}////////switch(lc-bf)
return T;
}
////右平衡处理
bstree RightBalance(bstree T)
{
bstree rc,ld;
rc=T-rchild; //rc指向*T的右子树根结点
switch(rc-bf) { //检查*T的右子树平衡度,并做相应的平衡处理
case RH: //新结点插入在*T的右孩子的右子树上,要做单右旋处理
T-bf=rc-bf=EH;
T=L_Rotate(T);
break;
case LH: //新结点插入在*T的右孩子的左子树上,要做双旋处理
ld=rc-lchild; //ld指向*T的右孩子的左子树根
switch(ld-bf){ //修改*T及其右孩子的平衡因子
case LH:
T-bf=EH;
rc-bf=RH;
break;
case EH:
T-bf=rc-bf=EH;
break;
case RH:
T-bf=LH;
rc-bf=EH;
break;
}///switch(ld-bf)
ld-bf=EH;
T-rchild=R_Rotate(T-rchild); //对*T的右孩子做右旋平衡处理
T=L_Rotate(T); //对*T做左旋处理
}/////switch(rc-bf)
return T;
}
int Delete(bstree T,int e){
//删除结点
bstree p,q;
e=0;
p=T;
if(!T-rchild) {//右子数为空需要重接它的左子数
T=T-lchild;
free(p);
shorter=true;
}
else if(!T-lchild) {//重接它的右子数
T=T-rchild;
free(p);
shorter=true;
}
else{ //左右子数均不空
q=T-lchild;
while(q-rchild!=NULL){//转左,然后向右到尽头
q=q-rchild;
}
e=q-data;
}
return e;
}
void Delete_Rightbalance(bstree T){
///////////删除在左子树上的,相当于插入在右子树
bstree rc=T-rchild,ld;
switch(rc-bf){
case LH://///////双旋 ,先右旋后左旋
ld=rc-lchild;
rc-lchild=ld-rchild;
ld-rchild=rc;
T-rchild=rc-lchild;
rc-lchild=T;
switch(ld-bf) {
case LH:T-bf=EH;
rc-bf=RH;
break;
case EH:T-bf=rc-bf=EH;
break;
case RH:T-bf=LH;
rc-bf=EH;
break;
}
ld-bf=EH;
T=rc;
shorter=true;break;
case EH:///////删除在左子树,相当于插入在右子树,左单旋
T-rchild=rc-lchild;
rc-lchild=T;
rc-bf=LH;
T-bf=RH;
T=rc;
shorter=EH;break;
case RH:///////删除在左子树,相当于插入在右子树,左单旋
T-rchild=rc-lchild;
rc-lchild=T;
rc-bf=T-bf=EH;
T=rc;
shorter=true;break;
}
}
void Delete_Leftbalance(bstree T)/////删除右子树上的,相当于插入在左子树上
{
bstree p1,p2;
p1=T-lchild;
switch(p1-bf) {
case LH:T-lchild=p1-rchild;//////右旋
p1-rchild=T;
p1-bf=T-bf=EH;
T=p1;
shorter=true;
break;
case EH:T-lchild=p1-rchild;///////右旋
p1-rchild=T;
p1-bf=RH;
T-bf=LH;
T=p1;
shorter=false;
break;
case RH:p2=p1-rchild;//////////右双旋
p1-rchild=p2-lchild;
p2-lchild=p1;
T-lchild=p2-rchild;
p2-rchild=T;
switch(p2-bf){
case LH:T-bf=RH;p1-bf=EH;break;
case EH:T-bf=EH;p1-bf=EH;break;
case RH:T-bf=EH;p1-bf=LH;break;
}
p2-bf=EH;
T=p2;
shorter=true;break;
}
}
3. 函数的调用关系图
Main
InsertAVL Preordertraverse FindAVL DeleteAVL
四、 调试分析
1. 在开始对平衡二叉树的插入后,再做平衡处理时,特别是在做双向旋转平衡处理后的更新时,费了一些时间;
2. 在做平衡二叉树的删除时,当删除结点左右孩子均在时,开始直接用左子树的最大数代替,然后直接删除结点,结果导致删除了将要删除的结点及其孩子均删除了,后来将要删除的结点用左子树的最大树代替后,对左子树的最大结点做好标记,然后再做对其做删除处理。
3. 本程序算法基本简单,没有多大困难,就是在分析做双旋平衡处理的更新时,开始思路有些混乱,后来就好了;
五、 用户手册
1. 本程序的运行环境为DOS操作系统,执行文件为Balanced Tree.exe。
2. 进入演示程序后,按广度遍历输入平衡二叉树,中间以回车键隔开,输入0为结束;再输入要插入的结点,输入0结束,再输入要查找的结点,最后可以输入要删除的结点,输入0结束
六、 测试结果
先按广度遍历创建平衡二叉树(亦可一个一个的插入二叉树的结点)(50 20 60 10 30 55 70 5 15 25 58 90) ,输入0结束,然后可插入结点(39),其会显示插入后的二叉树,输入0,不再插入;输入要查找结点(6),输入要删除的结点(20),其显示如下:
七、 附录
Balance Tree.cpp
Q2: 用java实现二叉树
我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某
个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,
那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往
后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑
了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,
public class Node {
public int value;
public Node left;
public Node right;
public void store(intvalue)
right.value=value;
}
else
{
right.store(value);
}
}
}
public boolean find(intvalue)
{
System.out.println("happen" +this.value);
if(value ==this.value)
{
return true;
}
else if(valuethis.value)
{
if(right ==null)returnfalse;
return right.find(value);
}else
{
if(left ==null)returnfalse;
return left.find(value);
}
}
public void preList()
{
System.out.print(this.value+ ",");
if(left!=null)left.preList();
if(right!=null) right.preList();
}
public void middleList()
{
if(left!=null)left.preList();
System.out.print(this.value+ ",");
if(right!=null)right.preList();
}
public void afterList()
{
if(left!=null)left.preList();
if(right!=null)right.preList();
System.out.print(this.value+ ",");
}
public static voidmain(String [] args)
{
int [] data =new int[20];
for(inti=0;idata.length;i++)
{
data[i] = (int)(Math.random()*100)+ 1;
System.out.print(data[i] +",");
}
System.out.println();
Node root = new Node();
root.value = data[0];
for(inti=1;idata.length;i++)
{
root.store(data[i]);
}
root.find(data[19]);
root.preList();
System.out.println();
root.middleList();
System.out.println();
root.afterList();
}
}
Q3: java二叉树的顺序表实现
做了很多年平衡二叉树代码java的程序员平衡二叉树代码java,觉得什么树平衡二叉树代码java的设计并不是非常实用。二叉树有顺序存储,当一个insert大量同时顺序自增插入的时候,树就会失去平衡。树的一方为了不让塌陷,会增大树的高度。性能会非常不好。以上是题外话。分析需求在写代码。
import java.util.List;
import java.util.LinkedList;
public class Bintrees {
private int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9};
private static ListNode nodeList = null;
private static class Node {
Node leftChild;
Node rightChild;
int data;
Node(int newData) {
leftChild = null;
rightChild = null;
data = newData;
}
}
// 创建二叉树
public void createBintree() {
nodeList = new LinkedListNode();
// 将数组的值转换为node
for (int nodeIndex = 0; nodeIndex array.length; nodeIndex++) {
nodeList.add(new Node(array[nodeIndex]));
}
// 对除最后一个父节点按照父节点和孩子节点的数字关系建立二叉树
for (int parentIndex = 0; parentIndex array.length / 2 - 1; parentIndex++) {
nodeList.get(parentIndex).leftChild = nodeList.get(parentIndex * 2 + 1);
nodeList.get(parentIndex).rightChild = nodeList.get(parentIndex * 2 + 2);
}
// 最后一个父节点
int lastParentIndex = array.length / 2 - 1;
// 左孩子
nodeList.get(lastParentIndex).leftChild = nodeList.get(lastParentIndex * 2 + 1);
// 如果为奇数,建立右孩子
if (array.length % 2 == 1) {
nodeList.get(lastParentIndex).rightChild = nodeList.get(lastParentIndex * 2 + 2);
}
}
// 前序遍历
public static void preOrderTraverse(Node node) {
if (node == null) {
return;
}
System.out.print(node.data + " ");
preOrderTraverse(node.leftChild);
preOrderTraverse(node.rightChild);
}
// 中序遍历
public static void inOrderTraverse(Node node) {
if (node == null) {
return;
}
inOrderTraverse(node.leftChild);
System.out.print(node.data + " ");
inOrderTraverse(node.rightChild);
}
// 后序遍历
public static void postOrderTraverse(Node node) {
if (node == null) {
return;
}
postOrderTraverse(node.leftChild);
postOrderTraverse(node.rightChild);
System.out.print(node.data + " ");
}
public static void main(String[] args) {
Bintrees binTree = new Bintrees();
binTree.createBintree();
Node root = nodeList.get(0);
System.out.println("前序遍历:");
preOrderTraverse(root);
System.out.println();
System.out.println("中序遍历:");
inOrderTraverse(root);
System.out.println();
System.out.println("后序遍历:");
postOrderTraverse(root);
}
}
平衡二叉树代码java的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于平衡二叉树程序、平衡二叉树代码java的信息别忘了在本站进行查找喔。







