二叉搜索树平衡调整


二叉搜索树:左边的节点的值总是比右边节点的值更大。
平衡二叉树:左右两边深度一样



平衡调整方式1

(不能保证是深度最小,只能是左右节点深度相差不超过1)部分代码截取

//平衡调整
public BST makeBalanced() {
    BST bst=new BST();
    bst.root=makeBalancedAssist(this.getRoot());

    return bst;
}


private Node makeBalancedAssist(Node root) {
    if (root==null){
        return null;
    }
    //获取左边节点
    Node leftNode=root.getLeft();
    //获取右边节点
    Node rightNode=root.getRight();
    //左节点递归
    root.setLeft(makeBalancedAssist(leftNode));
    //右节点递归
    root.setRight(makeBalancedAssist(rightNode));
      //获取左边节点深度
    int leftHeight = heightRecursive(root.getLeft());
    //获取右边节点深度
    int rightHeight = heightRecursive(root.getRight());
    //若不平衡,进行调整
    if (!isBalanced(root)){
        BST bst = new BST();
        bst.root=root;
        //LL
        if (leftHeight > rightHeight) {
            bst.root = singleRotateLeft(root);
            return makeBalancedAssist(bst.root);
        }
        //RR
        if (leftHeight < rightHeight) {
            bst.root=singleRotateRight(root);
            return makeBalancedAssist(bst.root);
        }
    }
    return root;
}
//判断是否平衡
private boolean isBalanced(Node root){
    if (root==null){
        return true;
    }
    int leftHeight = heightRecursive(root.getLeft());
    int rightHeight = heightRecursive(root.getRight());
    //左右节点深度差不超过1就平衡了
    if (Math.abs(leftHeight - rightHeight) <= 1&&isBalanced(root.getLeft())&&isBalanced(root.getRight())) {
        return true;
    }else {
        return false;
    }
}

//LL
private Node singleRotateLeft(Node root) {
    Node rightNodeTemp = root;
    Node leftNodeTemp = root.getLeft().getRight();
    root = root.getLeft();
    rightNodeTemp.setLeft(leftNodeTemp);
    root.setRight(rightNodeTemp);
    return root;
}

//RR
private Node singleRotateRight(Node root) {
    Node leftNodeTemp = root;
    Node rightNodeTemp = root.getRight().getLeft();
    root = root.getRight();
    leftNodeTemp.setRight(rightNodeTemp);
    root.setLeft(leftNodeTemp);
    return root;
}



将有序数组变为平衡二叉树

平衡调整方式2:将这个二叉搜索树为一个有序数组,然后将这个数组变成平衡二叉搜索树。

public Node sortedArrayToBST(String[] nums) {
   if(nums.length == 0){
         return null;
     }
     int index = nums.length / 2;
     Node node = new Node(nums[index]);
     String[] leftArray = new String[index];
     for(int i = 0;i<leftArray.length;i++) {
         leftArray[i] = nums[i];
     }
     node.left = sortedArrayToBST(leftArray);
     String[] rightArray = new String[nums.length - index - 1];
     for(int i = 0;i<rightArray.length;i++) {
         rightArray[i] = nums[index + 1 + i];
     }
     node.right = sortedArrayToBST(rightArray);
     return node;
}




节点类

public class Node{
  protected String data;
  protected Node   left;
  protected Node   right;

  public Node(String data){
    this(data, null, null);
  }

  public Node(String data, Node left, Node right){
    this.data = data;
    this.left = left;
    this.right = right;
  }

  public String getData(){return this.data;}
  public Node   getLeft(){ return this.left;}
  public Node   getRight(){ return this.right;}

  public void setData(String s){ this.data = s;}
  public void setLeft(Node left){ this.left = left;}
  public void setRight(Node right){ this.right = right;}
  public void setLeftRight(Node left, Node right){
    this.left = left;
    this.right = right;
  }
  public void setAll(String data, Node left, Node right){
    this.data = data;
    this.left = left;
    this.right = right;
  }
  

  public StringBuilder toString(StringBuilder prefix, boolean isTail, StringBuilder sb) {
    if(right!=null) {
        right.toString(new StringBuilder().append(prefix).append(isTail ? "\u2502   " : "    "), false, sb);
    }
    sb.append(prefix).append(isTail ? "\u2514\u2500\u2500 " : "\u250C\u2500\u2500 ").append(data.toString()).append("\n");
    if(left!=null) {
        left.toString(new StringBuilder().append(prefix).append(isTail ? "    " : "\u2502   "), true, sb);
    }
    return sb;
}


@Override
public String toString() {
    return this.toString(new StringBuilder(), true, new StringBuilder()).toString();
}

}

二叉树类


public class BinaryTree {
	protected Node root;
  protected int  size;

	public BinaryTree(){
		size = 0;
	}

  public BinaryTree(String s){
		root = new Node(s);
		size = 1;
	}

	public int getSize(){ return this.size; }
	public Node getRoot(){ return this.root; }


	public boolean contains(String target){
		if( root == null ){ return false; }
		if( root.getData().equals(target) ){
			return true;
		}
		return false;
	}





	public void add(String s){
		addLeft(s);
	}

	/* add a node in the left most free spot in the existing tree */
	private void addLeft(String s){
		if(root == null && size == 0){
			root = new Node(s);
			return;
		}else{
		  Node tmp = root;
		  while(tmp.getLeft() != null){
		  	tmp = tmp.getLeft();
		  }
		  // assert: temp.left == null
			// yea! we have a place to add s
		  tmp.setLeft(new Node(s));
		}
		size += 1;
	}
	




	/** Computes the height of the binary tree
	  *
		* The height is the length of the longest path from
		* the root of the tree to any other node.
		*
		* @return the height of the tree
		*/
	public int height(){
	  if( root == null ){ return -1; }
		return heightRecursive(root);
	}
	protected static int heightRecursive(Node root){
			if( root == null ){
			  return -1;
			}
			int leftHeight = heightRecursive(root.getLeft());
			int rightHeight = heightRecursive(root.getRight());
			if( leftHeight < rightHeight){
				return 1 + rightHeight;
			}else{
			  return 1 + leftHeight;
			}
		}


	public static void main(String[] args){
		BinaryTree t = new BinaryTree("cat");
		System.out.println("height = " + t.height() + ",  size = " + t.getSize());
		t.add("dog");
		t.add("eel");
		System.out.println("height = " + t.height() + ",  size = " + t.getSize());

	}
}

搜索二叉树已经平衡调整方式1完整代码

public class BST extends BinaryTree {

    
    public BST() {
        super();
    }


//判断是否包含某个节点    
    @Override
    public boolean contains(String s) {
        return isContains(s,this.root);
    }

    private boolean isContains(String s,Node root){
        if (root==null){
            return false;
        }else if (root!=null&&root.getData().equals(s)){
            return true;
        }else {
            boolean left=this.isContains(s,root.getLeft());
            boolean right=this.isContains(s,root.getRight());
            if (left||right){
                return true;
            }else {
                return false;
            }

        }
    }


//添加节点,大的数值在左边
    @Override
    public void add(String s) {
        if (s==null||s.equals("")){
            return;
        }
        if (root == null && size == 0) {
            root = new Node(s);
            return;
        } else {
            add(s, root);
        }

        size += 1;
    }

    private void add(String s, Node root) {
        Node tmp = root;
        if (tmp.getData().compareTo(s) < 0) {
            //add to right
            if (root.getRight() == null) {
                root.setRight(new Node(s));
                return;
            }
            add(s, root.getRight());
        } else {
            if (root.getLeft() == null) {
                root.setLeft(new Node(s));
                return;
            }
            add(s, root.getLeft());
        }
    }


	//是否是一个平衡二叉树
    public boolean isValidBST() {
        // the empty tree is a valid binary search tree
        if (this.size <= 0) {
            return true;
        }
        //returns true if this tree is a valid binary search tree, false otherwise
        if (this.root.getLeft() == null && this.root.getRight() == null) {
            return true;
        }
        return isValidBSTAssist(this.root);
    }

    private boolean isValidBSTAssist(Node node) {
        Node rootNode = node;
        if (rootNode == null) {
            return true;
        }
        Node leftNode = rootNode.getLeft();
        Node rightNode = rootNode.getRight();

        if (leftNode != null && leftNode.getData().compareTo(rootNode.getData()) > 0) {
            return false;
        }
        if (rightNode != null && rightNode.getData().compareTo(rootNode.getData()) < 0) {
            return false;
        }
        if (!isValidBSTAssist(leftNode)) {
            return false;
        }
        if (!isValidBSTAssist(rightNode)) {
            return false;
        }
        return true;
    }

	//平衡调整
    public BST makeBalanced() {
        BST bst=new BST();
        bst.root=makeBalancedAssist(this.getRoot());

        return bst;
    }


    private Node makeBalancedAssist(Node root) {
        if (root==null){
            return null;
        }
        //获取左边节点
        Node leftNode=root.getLeft();
        //获取右边节点
        Node rightNode=root.getRight();
        //左节点递归
        root.setLeft(makeBalancedAssist(leftNode));
        //右节点递归
        root.setRight(makeBalancedAssist(rightNode));
          //获取左边节点深度
        int leftHeight = heightRecursive(root.getLeft());
        //获取右边节点深度
        int rightHeight = heightRecursive(root.getRight());
        //若不平衡,进行调整
        if (!isBalanced(root)){
            BST bst = new BST();
            bst.root=root;
            //LL
            if (leftHeight > rightHeight) {
                bst.root = singleRotateLeft(root);
                return makeBalancedAssist(bst.root);
            }
            //RR
            if (leftHeight < rightHeight) {
                bst.root=singleRotateRight(root);
                return makeBalancedAssist(bst.root);
            }
        }
        return root;
    }
    //判断是否平衡
    private boolean isBalanced(Node root){
        if (root==null){
            return true;
        }
        int leftHeight = heightRecursive(root.getLeft());
        int rightHeight = heightRecursive(root.getRight());
        //左右深度差不超过1就平衡了
        if (Math.abs(leftHeight - rightHeight) <= 1&&isBalanced(root.getLeft())&&isBalanced(root.getRight())) {
            return true;
        }else {
            return false;
        }
    }

    //LL
    private Node singleRotateLeft(Node root) {
        Node rightNodeTemp = root;
        Node leftNodeTemp = root.getLeft().getRight();
        root = root.getLeft();
        rightNodeTemp.setLeft(leftNodeTemp);
        root.setRight(rightNodeTemp);
        return root;
    }

    //RR
    private Node singleRotateRight(Node root) {
        Node leftNodeTemp = root;
        Node rightNodeTemp = root.getRight().getLeft();
        root = root.getRight();
        leftNodeTemp.setRight(rightNodeTemp);
        root.setLeft(leftNodeTemp);
        return root;
    }


    public static void main(String[] args) {
    
        System.out.println("==================");
        BST bst=new BST();
        bst.add("a");
        bst.add("b");
        bst.add("aa");
        bst.add("ab");
        bst.add("ac");
        bst.add("c");
        bst.add("ba");
        bst.add("bb");
        bst.add("bc");
        bst.add("d");
        bst.add("ca");
        bst.add("e");
        bst.add("f");
        bst.add("g");
        System.out.println(bst.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        BST bst1=bst.makeBalanced();
        System.out.println(bst1.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        System.out.println(bst1.height());
    }


}



二叉搜索树和平衡二叉树调整方式2


public class BST extends BinaryTree {

    // You MUST have a zero argument constructor that
    // creates an empty binary search tree
    // You can can add code to this if you want (or leave it alone).
    // We will create all BSTs for testing using this constructor
    public BST() {
        super();
    }

    private MyLinkList<String> linkListNode;
    
    @Override
    public boolean contains(String s) {
        return isContains(s,this.root);
    }

    private boolean isContains(String s,Node root){
        if (root==null){
            return false;
        }else if (root!=null&&root.getData().equals(s)){
            return true;
        }else {
            boolean left=this.isContains(s,root.getLeft());
            boolean right=this.isContains(s,root.getRight());
            if (left||right){
                return true;
            }else {
                return false;
            }

        }
    }


    @Override
    public void add(String s) {
        if (s==null||s.equals("")){
            return;
        }
        if (root == null && size == 0) {
            root = new Node(s);
            linkListNode=new MyLinkList<>();
            linkListNode.add(s);
            return;
        } else {
            add(s, root);
            linkListNode.add(s);
        }

        size += 1;
    }

    private void add(String s, Node root) {
        Node tmp = root;
        if (tmp.getData().compareTo(s) < 0) {
            //add to right
            if (root.getRight() == null) {
                root.setRight(new Node(s));
                return;
            }
            add(s, root.getRight());
        } else {
            if (root.getLeft() == null) {
                root.setLeft(new Node(s));
                return;
            }
            add(s, root.getLeft());
        }
    }


    public boolean isValidBST() {
        // the empty tree is a valid binary search tree
        if (this.size <= 0) {
            return true;
        }
        //returns true if this tree is a valid binary search tree, false otherwise
        if (this.root.getLeft() == null && this.root.getRight() == null) {
            return true;
        }
        return isValidBSTAssist(this.root);
    }

    private boolean isValidBSTAssist(Node node) {
        Node rootNode = node;
        if (rootNode == null) {
            return true;
        }
        Node leftNode = rootNode.getLeft();
        Node rightNode = rootNode.getRight();

        if (leftNode != null && leftNode.getData().compareTo(rootNode.getData()) > 0) {
            return false;
        }
        if (rightNode != null && rightNode.getData().compareTo(rootNode.getData()) < 0) {
            return false;
        }
        if (!isValidBSTAssist(leftNode)) {
            return false;
        }
        if (!isValidBSTAssist(rightNode)) {
            return false;
        }
        return true;
    }


    public BST makeBalanced() {

        //sort
        String[] nodeArray=new String[linkListNode.getSize()];
        for (int i = 0; i < nodeArray.length; i++) {
            nodeArray[i]=linkListNode.get(i).data;
        }
        for (int i = 0; i < nodeArray.length-1; i++) {
            for (int j = 0; j < nodeArray.length - 1 - i; j++) {
                if (nodeArray[j].compareTo(nodeArray[j+1])>0){
                    String temp=nodeArray[j];
                    nodeArray[j]=nodeArray[j+1];
                    nodeArray[j+1]=temp;
                }
            }
        }

        BST bst=new BST();
        bst.root=sortedArrayToBST(nodeArray);
        return bst;
    }

    public Node sortedArrayToBST(String[] nums) {
        if(nums.length == 0){
            return null;
        }
        int index = nums.length / 2;
        Node node = new Node(nums[index]);
        String[] leftArray = new String[index];
        for(int i = 0;i<leftArray.length;i++) {
            leftArray[i] = nums[i];
        }
        node.left = sortedArrayToBST(leftArray);
        String[] rightArray = new String[nums.length - index - 1];
        for(int i = 0;i<rightArray.length;i++) {
            rightArray[i] = nums[index + 1 + i];
        }
        node.right = sortedArrayToBST(rightArray);
        return node;
    }



    class ListNode<T> {
        public ListNode next;
        public T data;

        public ListNode(T data) {
            this.data = data;
        }
    }

    class MyLinkList<T> {
        public ListNode first; // head
        private int pos = 0;// position
        private int size = 0;

        public MyLinkList() {
            this.first = null;
        }
        public MyLinkList(ListNode<T> first) {
            this.first = first;
        }

        // add in the last
        public void add(T data) {
            if (first == null) {
                first = new ListNode<T>(data);
                size++;
                return;
            }
            ListNode node = new ListNode<T>(data);
            ListNode current = first;
            while (current.next != null) {
                current = current.next;
            }
            current.next = node;
            size++;
        }
        public int getSize() {
            return size;
        }

        public ListNode<T> get(int index) {
            ListNode current = first;
            pos = 0;
            while (pos != index) {
                current = current.next;
                pos++;
            }
            return current;
        }

        public MyLinkList<T> change(int index){
            ListNode current = first;
            pos = 0;
            while (true) {
                if (pos == index){
                    T data= (T) current.data;
                    current.data=current.next.data;
                    current.next.data=data;
                    return new MyLinkList<>(first);
                }
                current = current.next;
                pos++;
            }
        }
    }


    public static void main(String[] args) {
        //test
        BST t = new BST();
        System.out.println("height = " + t.height() + ",  size = " + t.getSize());
        System.out.println(t.isValidBST());
        t.add(null);


        t.add("dog");
        t.add("eel");
        System.out.println("height = " + t.height() + ",  size = " + t.getSize());
        System.out.println(t.isValidBST());
        System.out.println(t.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));

        t.add("apple");
        System.out.println(t.isValidBST());
        System.out.println();
        System.out.println(t.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));

        t.add("ccdcc");
        t.add("hhhhh");
        t.add("jjjjj");
        t.add("vvvv");
        t.add("zzzz");
        System.out.println(t.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        System.out.println("c:"+t.contains("ccdcc"));

        System.out.println();
        System.out.println(t.root.data);

        BST b=t.makeBalanced();
        System.out.println(b.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        System.out.println(b.height());

        System.out.println("==================");
        BST bst=new BST();
        bst.add("a");
        bst.add("b");
        bst.add("aa");
        bst.add("ab");
        bst.add("ac");
        bst.add("c");
        bst.add("ba");
        bst.add("bb");
        bst.add("bc");
        bst.add("d");
        bst.add("ca");
        bst.add("e");
        bst.add("f");
        bst.add("g");
        System.out.println(bst.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        BST bst1=bst.makeBalanced();
        System.out.println(bst1.root.toString(new StringBuilder(" "),false,new StringBuilder(" ")));
        System.out.println(bst1.height());
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值