`

数据结构之查找(三)平衡二叉树

 
阅读更多

一、平衡二叉树

 

        定义特点是1.满足二叉查找树的特点

                             =》左子树小于根节点

                             =》右子树大于根节点

 

                          2.它的|左子树、与右子树的深度差|<2

                              =>目的是要充分的利用二叉查找树的特性,维护深度

 

二、实现

       

       为了维护它的特性,在插入添加的过程中会变得很复杂。参考

       1.首先来看下旋转

           =》对于树中的元素,还按照这个规则来重新实现

          例如:

 

          2.那么在平衡二叉树的插入过程当中会遇到哪些情况?

           (1)LL

                 

           解决办法=》找到最根的左、右子树深度不平衡的节点

                         =》然后根的左子树变根节点

                              =》然后根可以变成右子树

                              =》如果根的左子树有右子树,则变为此根的左子树

 

          (2)RR



           解决办法:同上相反

            

           (3)LR



            解决办法:首先调整成LL情况如何调整?

 

          (4)RL

                

            解决办法:首先调整成RR如何调整那?

 

三、代码实现

 

       =》节点结构

       =》查询

       =》添加

       =》实例化

       =》中序遍历

       =》效果图

       =》删除节点(实现了在)

 

//节点结构
class TreeNode{
	private int num;
	private int diff; //平衡因子
	private TreeNode leftChild;
	private TreeNode rightChild;
                 //get /set method	

}

 

//得到当前节点的深度

/*
	 * This will through recursion to get the deep
	 * but the deep does not contain the current node
	 * =>judge is null
	 *   =>null return
	 *   =>is not 
	 *     =>get the left and right
	 *     =>judge the left right return the max
	 * */
	public static int getDeep(TreeNode t){
   		
		if(t==null)return 0;
		
		int leftDeep=0;
		int rightDeep=0;
		
		leftDeep+=getDeep(t.getLeftChild());
		rightDeep+=getDeep(t.getRightChild());
		
		return leftDeep>=rightDeep?leftDeep+1:rightDeep+1;
	}

 

//实例化当前的节点的平衡因子
/*
	 * initialization the node attribute diff
	 * */
	public static void initDiff(TreeNode t){
		
		if(t==null)return;
		
	    int leftDeep=getDeep(t.getLeftChild());
	    int rightDeep=getDeep(t.getRightChild());
	    
	    t.setDiff(leftDeep-rightDeep);
	}

 

//递归实现插入操作
//解决了插入后平衡因子改变的记录
/*
	 *How to insert a number
	 *There have two method to input it
	 *
	 *if just insert the BST you can not user the recursion
	 *you can just get the insert node position
	 *
	 *use the recursion can get the path 
	 *that after insert the balance is interrupted
	 * */
	public static TreeNode insertBST(TreeNode t,int num){
		
		//if(searchBST(num))return false; 
		
		if(t==null){
			t=new TreeNode();
			t.setNum(num);
			t.setLeftChild(null);
			t.setRightChild(null);
            t.setDiff(0);
		}else{
			
//			if(t.getNum()==num){
//				return null;
//			}
			//there have the recursion
			//insert left
			if(t.getNum()>num){
				t.setLeftChild(insertBST(t.getLeftChild(), num));
				initDiff(t);
				//left-right=2;
				if(t.getDiff()==2){
					if(num<t.getLeftChild().getNum())
						t=LL(t);
					else
						t=LR(t);
				}
			}else if(t.getNum()<num){
				t.setRightChild(insertBST(t.getRightChild(),num));
				initDiff(t);
				if(t.getDiff()==-2){
					if(num>t.getRightChild().getNum())
						t=RR(t);
					else
						t=RL(t);
				}
			}
		}
		return t;
	}

 

//四个旋转情况
//LL
	/*
	 *     c        b     |       
	 *     /       /\     |
	 *    b   =>  a  c    |   
	 *   /                |  
	 *   a                | 
	 * */
	public static TreeNode LL(TreeNode t){
		TreeNode tn=t.getLeftChild();
		t.setLeftChild(tn.getRightChild());
		tn.setRightChild(t);
		
		initDiff(tn);
		initDiff(t);
		return tn;
	}
	
	//RR
	/*
	 * c           d  |
	 *  \         /\  |  
	 *   d   =>  c  e | 
	 *    \           |  
	 *     e          | 
	 * 
	 * */
	public static TreeNode RR(TreeNode t){
		TreeNode tn=t.getRightChild();
		t.setRightChild(tn.getLeftChild());
		tn.setLeftChild(t);
		
		initDiff(tn);
		initDiff(t);
		return tn;
	}
	
	//LR
	/*
	 *   d         d
	 *  /         /
	 * a    =>   b   =>
	 *  \      /
	 *   b    a
	 * */
	public static TreeNode LR(TreeNode t){
		t.setLeftChild(RR(t.getLeftChild()));
		return LL(t);
	}
	
	//RL
	public static TreeNode RL(TreeNode t){
		t.setRightChild(LL(t.getRightChild()));
		return RR(t);
	}
	

 

 

 

//删除操作
//当时在查询树的时候处理思路是这样的
//获得删除的节点,如果是叶子节点,那么它的父节点直接指向null
//如果只有左子树,则左子树替代位置
//如果只有右子树,右子树替代位置
//如果都有则,要么从最左边找到最大的代替然后,删除它
//或者从最右边找到最小的代替然后删除

//此处的思路是这样的
//如果没有右子树那么 左子树代替了
//如果有右子树,那么找到最小的右子树值,替换,删除

public static TreeNode deleteAVL(TreeNode t,int num){
		if(t==null)return null;
		else{
			if(t.getNum()==num){
			     //在查询二叉树的时候删除分为了
				 //叶子节点、只有左子树、只有右子树、有左右子树
				 //
				if(t.getRightChild()==null)t=t.getLeftChild();
				else{
					TreeNode tn=t.getRightChild();
					while(tn.getLeftChild()!=null)
						tn=tn.getLeftChild();
					
					t.setNum(tn.getNum());
					t.setRightChild(deleteAVL(t.getRightChild(),t.getNum()));
				    initDiff(t);
				    t.setDiff(t.getDiff()+1);
				}
				return t;
			}else if(t.getNum()>num){
				t.setLeftChild(deleteAVL(t.getLeftChild(),num));
			}else{
				t.setRightChild(deleteAVL(t.getRightChild(),num));
			}
			
		}
		   initDiff(t);
		   //删除一个节点结果只有+1 -1
		   if(t.getDiff()==2){
			   //必定是+1所致
               //删除的是右节点
			   //判断是LL 偶然LR
			   if(t.getLeftChild().getDiff()==1)
				   t=LL(t);
			   else if(t.getLeftChild().getDiff()==-1)
				   t=LR(t);
		   }else if(t.getDiff()==-2){
			   if(t.getRightChild().getDiff()==-1||t.getRightChild().getDiff()==0)
				   t=RR(t);
			   else if(t.getRightChild().getDiff()==1)
				   t=RL(t);
		   }
		return t;
	}

  

 

 

  • 大小: 47.1 KB
  • 大小: 19.3 KB
  • 大小: 18.3 KB
  • 大小: 26.6 KB
  • 大小: 26.8 KB
  • 大小: 4.1 KB
  • 大小: 6.3 KB
分享到:
评论

相关推荐

    2015广工数据结构实验--平衡二叉树(包含源码和实验报告

    2015广工数据结构实验--平衡二叉树(包含源码和实验报告

    数据结构实习--平衡二叉树的演示(C语言编写)+实验报告

    (2)初始时,平衡二叉树为空树,操作界面给出查找、插入和删除三种操作供选择。每种操作均要提示输入关键字。在查找时,如果查找的关键字不存在,则把其插入到平衡二叉树中。每次插入或删除一个结点后,应更新平衡...

    广工数据结构课程设计——平衡二叉树操作的演示

    广工数据结构课程设计——平衡二叉树操作的演示 内含源代码、可执行程序以及相应的说明文档 实验的功能包括: [实现提示] (1) 初始,平衡二叉树为空树,操作界面给出查找、插入和删除三种操作供选择。每种操作均要...

    数据结构平衡二叉树课程设计

    C语言编写的 数据结构 平衡二叉树 演示、含课程设计报告 多种输出平衡二叉树格式

    C++数据结构-二叉查找树和平衡二叉树

    实现了二叉查找树的查找、插入...实现了平衡二叉树(AVL树)的查找、插入、删除和迭代遍历的完整功能,插入时的各种旋转操作按照经典数据结构教材实现,并有详细的注释和说明。删除操作和相关旋转方法有单独描述文档。

    广工数据结构实验课程设计-平衡二叉树的演示

    广工数据结构课程设计——平衡二叉树操作的演示 内含源代码、可执行程序以及相应的说明文档 实验的功能包括: [实现提示] (1) 初始,平衡二叉树为空树,操作界面给出查找、插入和删除三种操作供选择。每种操作均要...

    03平衡二叉树_AVLTree.rar_03平衡二叉树_AVLTree_大话数据结构_平衡二叉树

    查找算法,平衡二叉树,大话数据结构里面的。

    数据结构(C语言)课程设计平衡二叉树

    1, 利用平衡二叉树实现一个动态查找表,实现动态查找表的三种基本功能:查找,插入、删除和附加的两种功能:合并、分裂平衡二叉树。 2, 操作界面要给创建、查找、插入、删除、合并和分裂六种操作供选择。每种操作...

    课设 - 平衡二叉树的演示 .docx

    (1) 构建一个平衡二叉树并实现创建、插入、查找、删除、销毁等操作。每种操作均提示输入关键字。每次插入或删除一个结点后,更新平衡二叉树的显示。 (2) 平衡二叉树的显示采用凹入表现形式。 (3)输入的...

    数据结构:实现平衡二叉树的各种算法

    用函数实现如下平衡二叉排序树算法: (1) 插入新结点 ...(5) 在二叉树中查找给定关键字(函数返回值为成功1,失败0) (6) 交换各结点的左右子树 (7) 求二叉树的深度 (8) 叶子结点数 (9) 删除某结点

    基于C写的平衡二叉树

    平衡二叉树结构的动态查找表 bool InitDSTable(BSTree * DT); bool DestoryDSTable(BSTree * DT); bool SearchDSTable(const BSTree DT,const KeyTypekey,ValueType * value); bool InsertDSTable(BSTree * DT,const...

    平衡二叉树

    数据结构C++版,平衡二叉树,实验,纯代码

    平衡二叉树 (从问题 -> 解决方案 -> 抽象出概念(如左旋右旋) -> 改进解决方案).zip

    平衡二叉树数据结构 平衡二叉树 = 二叉树 查找树 + 左右子树深度差不超过1: 为了解决不平衡导致的线性查询效率问题 二叉查找树 = 二叉树 + 左中右 大小顺序: 二分查找 二叉树 是链表结构  平衡二叉树...

    平衡二叉树的建立代码

    自己曾想上网搜建立平衡二叉树的代码,结果都不太满意,所以自己写了一个建树的程序,用户输入数据,程序根据数据的大小建立平衡二叉树,每输入一次数据则进行平衡操作,直到输入0结束,程序最后还会中序输出此平衡...

    数据结构 课程设计 二叉树

    本设计综合运用课本第六章和第九章的平衡二叉树和静态、动态查找表知识,设计程序来实现对平衡二叉树的插入、查找、删除等操作。

    平衡二叉树程序实现及完整文档

    利用二叉顺序树实现一个动态查找表,实现动态查找表的三项基本功能:查找,插入,删除操作。开始进行顺序二叉树的建立,输入元素的个数以及元素,动态创建一个二叉树,然后进行选择对二叉顺序树进行的操作,即选择,...

    平衡二叉树(纯C++实现)

    包含AVL树的创建,删除,查找等等功能,我使用的是VS2010的编译器,可能用版本低的编译器无法打开

    平衡二叉树操作演示课程设计

    system("title 平衡二叉树操作演示"); Print(); scanf("%d",&s); while(s!=8){ switch(s) { case1: //显示 printf("\t&gt;&gt;-显示-); printf("T:\n"); ViewTree(T,5); printf("t:\n"); ViewTree(t,5); ...

    二叉排序树与平衡二叉树的实现

    平衡二叉树是在构造二叉排序树的过程中,每当插入一个新结点时,首先检查是否因插入新结点而破坏了二叉排序树的平衡性,若是,则找出其中的最小不平衡子树,在保持二叉排序树特性的前提下,调整最小不平衡子树中各...

Global site tag (gtag.js) - Google Analytics