二叉搜索树的JAVA实现-201805

 

这里就贴下过程了


package for_test;

import java.util.Stack;

//二叉树-不允许重复元素
public class BinaryTree {
	public static void main(String[] args) {
		Tree n = new Tree();
		n.insert(15);
		n.remove(15);
		System.out.println("1.----"+n.getRoot());
		n.insert(15);
		n.insert(1);
		n.insert(-10);
		n.insert(10);
		n.insert(20);
		n.insert(16);
		n.insert(22);
		n.insert(5);
		n.insert(-5);
//		n.insert(6);
//		n.insert(11);
		n.printTree(n.getRoot(), 0);
		System.out.println(n.getRoot());
		System.out.println(n.getRoot().parent);
		//Nord test = n.get(10);
		//System.out.println(test.parent);
		System.out.println("中序遍历(递归):");
		n.walkInOrder(n.getRoot());
		System.out.println("中序遍历(非递归):");
		n.walkInOrder2(n.getRoot());
		System.out.println("前序遍历(递归):");
		n.walkPreOrder(n.getRoot());
		System.out.println("前序遍历(非递归):");
		n.walkPreOrder2(n.getRoot());
		System.out.println("后序遍历(递归):");
		n.walkPostOrder(n.getRoot());
		System.out.println("后序遍历(非递归):");
		n.walkPostOrder2(n.getRoot());
		System.out.println("最大值:" + n.max(n.getRoot()));
		System.out.println("最小值:" + n.min(n.getRoot()));
		System.out.println("节点个数:"+n.size(n.getRoot()));
		System.out.println("树的深度:"+n.depth(n.getRoot()));
		n.remove(15);
		n.printTree(n.getRoot(), 0);
		System.out.println(n.getRoot());
		System.out.println(n.getRoot().parent);
		n.walkInOrder(n.getRoot());
		n.destroy(n.getRoot());
		System.out.println(n.size(n.getRoot()));
		
		
	}

}

class Tree {
	private Nord root;

	public Tree() {
	}

	public Tree(Nord root) {
		root = this.root;
	}

	public Nord getRoot() {
		return root;
	}

	public void setRoot(Nord root) {
		this.root = root;
	}
	
	// 找到根节点
	public Nord root(Nord x) {
		for (Nord p = x, r;;) {
			if ((r = p.parent) == null) {
				return p;
			}
			p = r;
		}
	}

	// 删除元素为x的节点
	public boolean remove(int x) {
		return remove(get(x));
	}

	/**
	 * 参考算法导论-第12章
	 * 
	 * 删除后的结构调整: 1.若x没有子节点,则简单删除x,修改父节点,使用null替换x 2.若x只有一个子节点z,则删除x,使用z替换x
	 * 3.若x有两个子节点,则x的后继y(此时一定在x的右子树中,且y的左孩子节点为null)将替代x的位置。
	 * 若y为x的右孩子,则将y.left=x.left;若y不是x的右孩子,则将y.parent.right=y.right,y.right=x.right;
	 * 
	 * 具体算法: 1.若x.left=NULL,则transplant(x,x.right);
	 * 2.否则,若x.right=null,则transplant(x,x.left); 3.
	 * 若x.right!=null,x的后继y=min(x.right)[这里参考sucessor算法],若y.parent=x,则transplant(x,y),y.left=x.left,y.left.parent=y;
	 * 若y.parent!=x,则先transplant(y,y.right),y.right=x.right,y.right.parent=y,再用y替代x的位置.
	 * 
	 */
	public boolean remove(Nord x) {
		if (x != null) {
			Nord y;
			if (x.right == null) {
				transplant(x, x.left);
			} else if (x.left == null) {
				transplant(x, x.right);
			} else {
				if ((y = min(x.right)) != x.right) {
					transplant(y, y.right);
					y.right = x.right;
					y.right.parent = y;
				}
				transplant(x, y);
				y.left = x.left;
				y.left.parent = y;
			}
			return true;
		}
		return false;
	}

	// 将以y为根的子树替换以x为根的子树,此时x的父节点变为y的父节点,y为相应的孩子节点
	public boolean transplant(Nord x, Nord y) {
		if (x != null) {
			Nord p;
			if ((p = x.parent) == null) {
				if(y!=null) {
					this.root = y;
					y.parent=null;
				}else {
					this.root=null;
				}
			} else {
				if (x == p.left) {
					p.left = y;
				} else {
					p.right = y;
				}
				if (y != null) {
					y.parent = p;
				}
			}
			return true;
		}
		return false;
	}

	// 查找节点x的后继sucessor(大于x.element的最小节点)
	/**
	 * 分两种情况: 若x的右子树非空,则返回min(x); 若x的右子树为空,则返回根节点;
	 */

	public Nord successor(Nord x) {
		if (x != null) {
			if (x.right != null) {
				return min(x.right);
			}
			Nord y = x.parent;
			while (y != null && y.right == x) {
				x = y;
				y = y.parent;
				// return this.root;
			}
			return y;
		}
		return null;
	}

	// 查找节点x的前驱predecessor(小于x.element的最大节点)
	public Nord predecessor(Nord x) {
		if (x != null) {
			if (x.left != null) {
				return max(x.left);
			}
			Nord y = x.parent;
			while (y != null && y.left == x) {
				x = y;
				y = y.parent;
			}
			return y;
		}
		return null;
	}

	// 查找最大值
	public Nord max(Nord root) {
		if (root != null) {
			while (root.right != null) {
				root = root.right;
			}
			return root;
		}
		return null;
	}

	// 查找最小值
	public Nord min(Nord root) {
		if (root != null) {
			while (root.left != null) {
				root = root.left;
			}
			return root;
		}
		return null;
	}

	// 中序遍历(递归)- 1.先访问其左子树 2.访问根节点3.访问其右子树
	public void walkInOrder(Nord root) {
		if (root != null) {
			walkInOrder(root.left);
			System.out.println(root.element);
			walkInOrder(root.right);
		}
	}
	
	// 中序遍历(非递归)
	public void walkInOrder2(Nord root) {
		Stack<Nord> s=new Stack<>();
		Nord p=root;
		while(s.size()>0 || p!=null) {
			while(p!=null) {
				s.push(p);
				p=p.left;
			}
			if(s.size()>0) {
				p=s.pop();
				System.out.println(p.element);
				p=p.right;
			}	
		}		
	}

	// 前序遍历(递归)-1.先访问根节点 2.访问其左子树 3.访问其右子树
	public void walkPreOrder(Nord root) {
		if (root != null) {
			System.out.println(root.element);
			walkPreOrder(root.left);
			walkPreOrder(root.right);
		}
	}
	
	// 前序遍历(非递归)
	public void walkPreOrder2(Nord root) {
		Stack<Nord> s=new Stack<>();
		Nord p=root;
		while(s.size()>0 || p!=null) {
			while(p!=null) {
				System.out.println(p.element);
				s.push(p);
				p=p.left;
			}
			if(s.size()>0) {
				p=s.pop();
				p=p.right;
			}
		}
	}
	
	// 后序遍历(递归)- 1.先访问其左子树 2.访问其右子树 3.最后访问根节点
	public void walkPostOrder(Nord root) {
		if (root != null) {
			walkPostOrder(root.left);
			walkPostOrder(root.right);
			System.out.println(root.element);
		}
	}
	
	// 后序遍历(非递归) 参考:https://blog.csdn.net/wuwenxiang91322/article/details/12231657
	public void walkPostOrder2(Nord root) {
		Stack<Nord> s=new Stack<>();
		Nord p=root;
		while(p!=null) {
			for(;p.left!=null;p=p.left) {
				s.push(p);
			}
			while(p!=null &&(p.right==null || p.right==root)) {
				System.out.println(p.element);
				root=p;
				if(s.empty()) {
					return;
				}
				p=s.pop();
			}
			s.push(p);
			p=p.right;
		}
	}
	
	// 查找节点
	public Nord get(int x) {
		return get(root, x);
	}

	// 查找节点
	public Nord get(Nord root, int x) {
		if (root == null || x == root.element) {
			return root;
		}
		if (root.element > x) {
			return get(root.left, x);
		} else {
			return get(root.right, x);
		}
	}

	// insert
	public boolean insert(int item) {
		return insert(root, item);
	}

	// insert插入
	public boolean insert(Nord root, int item) {
		Nord nord = new Nord(null, null, null, item);
		int rt;
		Nord p = null;
		while (root != null) {
			p = root;
			if ((rt = root.element) > item) {
				root = root.left;
			} else if (rt < item) {
				root = root.right;
			} else {
				return false;
			}
		}
		if (p != null) {
			nord.parent = p;
			if (p.element < item) {
				p.right = nord;
			} else if (p.element > item) {
				p.left = nord;
			}
		} else {
			this.root = nord;
		}
		return true;
	}
	
	
	//删除整棵树
	public void destroy(Nord root) {
		if(root!=null) {
			destroy(root.left);
			destroy(root.right);
			remove(root);
		}	
	}
	
	//树的节点个数
	public int size(Nord root) {
		if(root==null) {
			return 0;
		}
		return 1+size(root.left)+size(root.right);
	}
	
	//树的深度
	public int depth(Nord root) {
		if(root==null) {
			return 0;
		}
		int l,r;
		return (l=depth(root.left))>(r=depth(root.right))?(1+l):(1+r);		
	}
	
	//凹入法打印(将树逆时针旋转90°后打印)
	public void printTree(Nord root,int n) {
		if(root!=null) {
			printTree(root.right,n+1);
			for(int i=0;i<n;i++) System.out.print("   ");
			System.out.print("-- ");
			System.out.print(root.element+"\n");
			printTree(root.left,n+1);
		}		
	}
	
	/**
	 * 节点的结构采用链式存储:三叉链结构
	 */
	class Nord {

		Nord parent;
		Nord left;
		Nord right;
		int element;

		Nord(Nord parent, Nord left, Nord right, int element) {
			super();
			this.parent = parent;
			this.left = left;
			this.right = right;
			this.element = element;
		}

		@Override
		public String toString() {
			return "Nord  [element=" + element + "]";
		}
	}

}
结果:
1.----null
      -- 22
   -- 20
      -- 16
-- 15
      -- 10
         -- 5
   -- 1
         -- -5
      -- -10
Nord  [element=15]
null
中序遍历(递归):
-10
-5
1
5
10
15
16
20
22
中序遍历(非递归):
-10
-5
1
5
10
15
16
20
22
前序遍历(递归):
15
1
-10
-5
10
5
20
16
22
前序遍历(非递归):
15
1
-10
-5
10
5
20
16
22
后序遍历(递归):
-5
-10
5
10
1
16
22
20
15
后序遍历(非递归):
-5
-10
5
10
1
16
22
20
15
最大值:Nord  [element=22]
最小值:Nord  [element=-10]
节点个数:9
树的深度:4
      -- 22
   -- 20
-- 16
      -- 10
         -- 5
   -- 1
         -- -5
      -- -10
Nord  [element=16]
null
-10
-5
1
5
10
16
20
22
0


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值