【典型习题整理】数据结构与算法作业

数据结构与算法


Binary Search Tree

概念

       二叉搜索树
       由于其左子树总是小于当前节点key值又小于右子树,所以这种数据结构在搜索中经常用到。
       但值得注意的是,这种树如果分布地很均衡的话搜索的时间复杂度为O(log2n),但如果输入的数据流恰好为顺序表的话,这棵树的搜索时间复杂度和链表一样O(n)。

代码实现:

package ElevenWeek;

import java.util.*;

public class BSTNode {//Binary Search Node class

	private class Node{//子类
		
		public Node left;
		public Node right;
		public int key;

		public Node(int x){this.key=x;}
	}
	
	public Node root;
	public int size;
	
	public BSTNode(){
		this.root=null;
		this.size=0;
	}
	
	public boolean isEmpty(){ return size==0;}
	
	public void add(int x){ root=add(root, x);}
	private Node add(Node node, int x){
		if(node==null){
			size++;
			return new Node(x);
		}
		
		if(node.key > x) node.left=add(node.left, x);
		else if(node.key < x) node.right=add(node.right, x);
		
		return node;
	}
	
	public boolean contains(int x){ return contains(root, x);}
	private boolean contains(Node node, int x){
		
		if(node==null) return false;
		if(node.key==x) return true;
		else if(node.key>x) return contains(node.left, x);
		else return contains(node.right, x);
	}
	
	private void visit(Node node){System.out.print(node.key+", ");}
	/**
	* 以下为先序遍历,中序遍历,后序遍历,层序遍历的非递归实现
	*
	* 其中Stack类我在前期中有写过
	*/
	public void preTravel() throws Exception{ preTravel(root);}
	private void preTravel(Node node) throws Exception{
		if(node==null) return;
		
		Stack s=new Stack(20);
		s.push(node);
		Node temp;
		
		while(!s.isEmpty()){
			temp=(Node) s.pop();
			visit(temp);
			if(temp.right!=null) s.push(temp.right);
			if(temp.left!=null) s.push(temp.left);
		}
		System.out.println();
	}
	
	public void midTravel() throws Exception{ midTravel(root);}
	private void midTravel(Node node) throws Exception{
		if(node==null) return;
		
		Stack s=new Stack(20);
		
		while(true){
			while(node!=null){
				s.push(node);
				node=node.left;
			}
			if(s.isEmpty()) break;
			node=(Node) s.pop();
			visit(node);
			node=node.right;
		}
		System.out.println();
	}
	
	public void bacTravel() throws Exception{ bacTravel(root);}
	private void bacTravel(Node node) throws Exception {
		if(node==null) return;
		
		Node curnode=node;
		Node prenode=null;
		Stack s=new Stack(20);
		
		while(curnode!=null){
			s.push(curnode);
			curnode=curnode.left;
		}
		
		while(!s.isEmpty()){
			curnode=(Node) s.pop();
			if(curnode.right==null||curnode.right==prenode){
				visit(curnode);
				prenode=curnode;
				continue;
			}
			s.push(curnode);
			curnode=curnode.right;
			while(curnode!=null){
				s.push(curnode);
				curnode=curnode.left;
			}
		}
		System.out.println();
	}
	
	public void levTravel(){ levTravel(root);}
	private void levTravel(Node node){
		if(node==null) return;
		
		Queue<Node> q=new LinkedList<Node>();
		q.offer(node);
		
		while(!q.isEmpty()){
			node=q.poll();
			visit(node);
			
			if(node.left!=null) q.offer(node.left);
			if(node.right!=null) q.offer(node.right);
		}
		System.out.println();
	}
	
	public int getMin() throws Exception{
		if(size==0) throw new Exception("BST is empty.");
		return getMin(root).key;
	}
	private Node getMin(Node node){
		while(node.left!=null){
			node=node.left;
		}
		return node;
	}
	
	public int getMax() throws Exception{
		if(size==0) throw new Exception("BST is empty.");
		return getMax(root).key;
	}
	private Node getMax(Node node){
		while(node.right!=null) node=node.right;
		return node;
	}
	
	public int delMin() throws Exception{
		int min=getMin();
		root=delMin(root);
		return min;
	}
	private Node delMin(Node node){
		if(node.left==null) return null;
		while(node.left.left!=null) node=node.left;
		node.left=null;
		return node;
	}
	
	public int delMax() throws Exception{
		int max=getMax();
		root=delMax(root);
		return max;
	}
	private Node delMax(Node node){
		if(node.right==null) return null;
		while(node.right.right!=null) node=node.right;
		node.right=null;
		return node;
	}
	
	public void remove(int x){ root=remove(root, x);}
	private Node remove(Node node, int x){
		if(node==null) return null;
		
		if(node.key>x){
			node.left=remove(node.left, x);
			return node;
		}
		else if(node.key<x){
			node.right=remove(node.right, x);
			return node;
		}
		else{
			if(node.left==null){
				Node temp=node.right;
				node.right=null;
				size--;
				return temp;
			}
			if(node.right==null){
				Node temp=node.left;
				node.left=null;
				size--;
				return temp;
			}
			// 待删除节点左右子树均不为空的情况
			// 查找待删除节点的后继节点
			// 用后继节点替换当前待删除节点
			Node prenode=getMin(node.right);
			prenode.right=delMin(node.right);
			prenode.left=node.left;
			node.left=null;
			node.right=null;
			return prenode;
		}
	}
	
	public String toString(){
		String res="";
		generateString(root, 0, res);
		return res;
	}
	
	private void generateString(Node node, int depth, String res){
		if(node==null){
			res+=generate_nbsp(depth)+"null\n";
			return;
		}
		
		res+=generate_nbsp(depth)+node.key+"\n";
		generateString(node.left, depth+1, res);
		generateString(node.right, depth+1, res);
	}
	private String generate_nbsp(int depth){
		String res="";
		for(int i=0;i<depth;i++)
			res+="--";
		return res;
	}
}

Test:

package ElevenWeek;

public class BSTree_Test {
	
	public static void main(String args[]) throws Exception{
		int[] nums={5,3,6,4,8,2};
		BSTNode bs=new BSTNode();
		for(int i=0;i<nums.length;i++)
			bs.add(nums[i]);
		
		System.out.println("pre in the first time: ");
		bs.preTravel();
		System.out.println("mid");
		bs.midTravel();
		System.out.println("bac");
		bs.bacTravel();
		System.out.println();
		
		bs.remove(bs.getMax());
		System.out.println("pre");
		bs.preTravel();
		System.out.println("mid");
		bs.midTravel();
		System.out.println("bac");
		bs.bacTravel();
		System.out.println();
		
		bs.add(8);
		bs.remove(3);
		System.out.println("pre");
		bs.preTravel();
		System.out.println("mid");
		bs.midTravel();
		System.out.println("bac");
		bs.bacTravel();
		System.out.println();
	}
}

结果:

pre in the first time:
5, 3, 2, 4, 6, 8,
mid
2, 3, 4, 5, 6, 8,
bac
2, 4, 3, 8, 6, 5,

pre
5, 3, 2, 4, 6,
mid
2, 3, 4, 5, 6,
bac
2, 4, 3, 6, 5,

pre
5, 4, 2, 6, 8,
mid
2, 4, 5, 6, 8,
bac
2, 4, 8, 6, 5,

AVT Tree

概念:

       平衡二叉树
       考虑到Binary Search Tree对于输入数据顺序的高度依赖,AVL Tree用于自动平衡二叉树,以确保每次搜索的时间复杂度总为O(log2n)。

代码实现:

package ElevenWeek;

import java.util.*;

public class AVLNode {

private class Node{
		
		public int key;
		public Node left;
		public Node right;
		public int height;
		
		public Node(int x, Node left, Node right){
			this.key=x;
			this.left=left;
			this.right=right;
		}
		
		public Node(int x){
			this.key=x;
			this.left=null;
			this.right=null;
		}
	}
	
	private static final int allow_balance=1;
	private Node root=null;
	public AVLNode(){root=null;}
	
	public boolean isEmpty(){return root==null;}
	
	public void insert(int x){root=insert(root, x);}
	
	private Node insert(Node node, int x) {
		// TODO Auto-generated method stub
		if(node==null) return new Node(x);
		if(x > node.key) node.right=insert(node.right, x);
		else if(x < node.key) node.left=insert(node.left, x);
		return balance(node);
	}
	
	private Node balance(Node node){
		if(node==null) return node;
		if(height(node.left) - height(node.right) > allow_balance){
			if(height(node.left.left) >= height(node.left.right)) node = rotate_with_left(node);
			else node = double_with_left(node);
		}
		else if(height(node.right) - height(node.left) > allow_balance){
			if(height(node.right.right) >= height(node.right.left)) node=rotate_with_right(node);
			else node=double_with_right(node);
		}
		node.height=Math.max(height(node.left), height(node.right))+1;
		return node;
	}

	private int height(Node node){return (node==null) ? 0 : Math.max(height(node.left), height(node.right))+1;}

	private Node rotate_with_left(Node node) {
		Node tempnode=node.left;
		node.left=tempnode.right;
		tempnode.right=node;
		node.height=Math.max(height(node.left), height(node.right))+1;
		tempnode.height=Math.max(height(tempnode.left), height(tempnode.right))+1;
		return tempnode;
	}
	
	private Node rotate_with_right(Node node){
		Node tempnode=node.right;
		node.right=tempnode.left;
		tempnode.left=node;
		node.height=Math.max(height(node.left), height(node.right))+1;
		tempnode.height=Math.max(height(tempnode.left), height(tempnode.right))+1;
		return tempnode;
	}
	
	private Node double_with_left(Node node){
		node.left=rotate_with_right(node.left);
		return rotate_with_left(node);
	}
	
	private Node double_with_right(Node node){
		node.right=rotate_with_left(node.right);
		return rotate_with_right(node);
	}
	
	public void remove(int x){root=remove(root, x);}
	
	private Node remove(Node node, int x){
		if(node==null) return node;
		if(x < node.key) node.left=remove(node.left, x);
		else if(x > node.key) node.right=remove(node.right, x);
		else if(node.left!=null&&node.right!=null){
			node.key=findmin(node.right).key;
			node.right=remove(node.right, node.key);
		}
		else node = (node.left==null) ? node.right : node.left;
		return balance(node);
	}
	
	public Node findmin(Node node){
		if(node==null) return null;
		if(node.left==null) return node;
		return findmin(node.left);
	}
	
	public void levTravel(){
		Queue<Node> q=new LinkedList<Node>();
		q.offer(root);
		Node temp;
		
		while(!q.isEmpty()){
			temp=q.poll();
			visit(temp);
			if(temp.left!=null) q.offer(temp.left);
			if(temp.right!=null) q.offer(temp.right);
		}
		System.out.println();
	}
	
	public void preTravel() throws Exception{ preTravel(root);}
	private void preTravel(Node node) throws Exception{
		if(node==null) return;
		
		Stack s=new Stack(20);
		s.push(node);
		while(!s.isEmpty()){
			node=(Node) s.pop();
			visit(node);
			if(node.right!=null) s.push(node.right);
			if(node.left!=null) s.push(node.left);
		}
		System.out.println();
	}
	
	public void midTravel() throws Exception{ midTravel(root);}
	private void midTravel(Node node) throws Exception{
		if(node==null) return;
		
		Stack s=new Stack(20);
		while(true){
			while(node!=null){
				s.push(node);
				node=node.left;
			}
			if(s.isEmpty()) break;
			node=(Node) s.pop();
			visit(node);
			node=node.right;
		}
		System.out.println();
	}
	
	public void bacTravel() throws Exception{ bacTravel(root);}
	private void bacTravel(Node node) throws Exception {
		if(node==null) return;
		
		Stack s=new Stack(20);
		Node curnode=node;
		Node prenode=null;
		
		while(curnode!=null){
			s.push(curnode);
			curnode=curnode.left;
		}
		while(!s.isEmpty()){
			curnode=(Node) s.pop();
			if(curnode.right==null||curnode.right==prenode){
				visit(curnode);
				prenode=curnode;
				continue;
			}
			s.push(curnode);
			curnode=curnode.right;
			while(curnode!=null){
				s.push(curnode);
				curnode=curnode.left;
			}
		}
		System.out.println();
	}

	private void visit(Node temp) {
		// TODO Auto-generated method stub
		System.out.print(temp.key+", ");
	}
}

Test

package ElevenWeek;

public class AVLNode_Test {
	
	public static void main(String args[]) throws Exception{
		
		AVLNode as=new AVLNode();
		as.insert(1);
		as.insert(2);
		as.insert(3);
		as.insert(4);
		as.insert(5);
		as.insert(6);
		as.insert(7);
		as.insert(8);
		as.insert(9);
		System.out.println("pre in the first time: ");
		as.preTravel();
		System.out.println("mid");
		as.midTravel();
		System.out.println("bac");
		as.bacTravel();
		System.out.println();
	}
}

结果如下:

pre in the first time:
4, 2, 1, 3, 6, 5, 8, 7, 9,
mid
1, 2, 3, 4, 5, 6, 7, 8, 9,
bac
1, 3, 2, 5, 7, 9, 8, 6, 4,

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值