树-完全二叉树

 树的优点:
(1):表示某一个领域的层次结构,而链表和数组都是现行一维的,无法表示层次结构
(2):二叉排序树进行查找比链表快的多。但是这个条件并非总是成立,取决于树的结构,如果树高度平衡(任意节点的两个子树的高度差
为0或1),则查找对象快,如果树中对象分布不均匀,则
完全二叉树(complete binary tree)或者完全平衡树:当树是平衡的并且所有的叶子节点都在一层或者两层则这棵树是完全平衡树。
如果在一棵完全平衡树中存储10000个元素,那么树的高度为lg[10001] = 14,也就是最多需要检查14个节点就能找到一个元素。比链表需要
10000此检查有着巨大的差距。

该算法的优点是:无须开辟额外的空间用于存储节点,时间复杂度线性O(n)。
该算法分两个阶段进行:首先将任意一颗二叉树通过一序列右旋转(right rotations)转换成一个单链结构(称作vine,即每个非叶子节点只有右孩子,没有左孩子);
然后在第二阶段中对单链结构通过几个批次左旋转(left rotations)生成一颗完全二叉树。为了生成完全二叉树,
在第二阶段的左旋转中,首先只将一部分节点左旋转(这算是第一个批次左旋转),
然后依次对剩下的单链节点做多批次左旋转(每个批次的左旋转所针对的节点位于剩下的vine上依次相隔的一个节点),
直到某个批次的左旋转次数不大于1。

 二叉排序树通过DSW算法平衡成完全二叉树算法

定义节点数据域:

package cn.com.chenlly;

public class Persion {
	private int id;
	private String name;
	private double height;

	// 构造函数
	public Persion(int id, String name, double height) {
		this.id = id;
		this.name = name;
		this.height = height;
	}

	// 重写equals 方法
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}

		if (obj == this) {
			return true;
		}

		if (!(obj instanceof Persion)) {
			return false;
		}

		Persion persion = (Persion) obj;
		return persion.id == this.id && persion.name == this.name
				&& persion.height == this.height;
	}

	// 重写 toString方法
	public String toString() {
		return "[id:" + id + ",name:" + name + ",height:" + height + "]";
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
}


定义节点:

package cn.com.chenlly;

public class Node {
	private Persion persion;  //数据域
	private Node leftChild;
	private Node rightChild;
	
	public Node(Persion p){
		this.persion = p; 
	}
	
	public Persion getPersion() {
		return persion;
	}
	public void setPersion(Persion persion) {
		this.persion = persion;
	}
	public Node getLeftChild() {
		return leftChild;
	}
	public void setLeftChild(Node leftChild) {
		this.leftChild = leftChild;
	}
	public Node getRightChild() {
		return rightChild;
	}
	public void setRightChild(Node rightChild) {
		this.rightChild = rightChild;
	}

}


一次性平衡二叉树(DSW算法)

package cn.com.chenlly;

public class BinaryTree {
	
	private static int[] idArray = new int[]{64,32,100,90,120,130,150,10}; 
	private Node root;

	public Node getRoot() {
		return root;
	}

	public BinaryTree() {
		
	}
	
	/**
	 * 把一个新节点插入到二叉排序树中
	 * @param newNode
	 */
	public void insert(Node newNode){
		if(root == null){
			root = newNode;
		} else {
			Node current  = root;
			Node parent;
			while(true){
				parent = current;
				if(newNode.getPersion().getId()<current.getPersion().getId()){
					//当前节点下移
					current = current.getLeftChild();
					if(current==null){
						//到了叶子节点
						parent.setLeftChild(newNode);
						return ;
					}
				} else {
					current = current.getRightChild();
					if(current==null){
						parent.setRightChild(newNode);
						return;
					}
				}
			}
		}
	}
	
	public void creatBT(){
		//构造二叉排序树
		for(int id:idArray){
			Persion p = new Persion(id,null,0.0);
			Node node = new Node(p);
			insert(node);
		}
	}
	
	/**
	 *前序遍历
	 * @param node
	 */
	public void preOrder(Node node){
		if(node!=null){
			System.out.print(node.getPersion().getId()+",");
			preOrder(node.getLeftChild());
			preOrder(node.getRightChild());
		}
	}
	
	/**
	 * 任意一颗二叉树通过一序列右旋转(right rotations)转换成一个单链结构
	 * (称作vine,即每个非叶子节点只有右孩子,没有左孩子),
	 * 也就是对节点按从小到大排序
	 */
	public Node createVine(Node root){
		//创建一个最小的node
		Node minNode = new Node(new Persion(-100,null,0.0));
		Node grandpar = minNode;
		Node temp = root;
		while(temp!=null){
			if(temp.getLeftChild()!=null){
				Node child = temp.getLeftChild();
				temp.setLeftChild(child.getRightChild());
				child.setRightChild(temp);
				temp = child;
			} else {
				grandpar.setRightChild(temp);
				grandpar = temp;
				temp = temp.getRightChild();
			}
		}
		
		root = minNode.getRightChild();
		return root;
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BinaryTree bt = new BinaryTree();
		//创建一课二叉排序树树(BST)
		bt.creatBT();
		//前序遍历
		System.out.println("前序遍历结果:");
		bt.preOrder(bt.getRoot());
		//右旋转(right rotations)转换成一个单链结构
		Node root1 = bt.createVine(bt.getRoot());
		System.out.println();
		System.out.println("右顺转结果:");
		bt.preOrder(root1);
	}

}


输出结果:

前序遍历结果:
64,32,10,100,90,120,130,150,
右顺转结果:
10,32,64,90,100,120,130,150,

 

 

bt.creatBT();创建的二叉排序树图示

bt.createVine(bt.getRoot()); 右顺转后的二叉排序树图示


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值