Java基础之梳理二叉树操作

二叉树学习简介

二叉树是数据结构的一种。
二叉树的特点:左子树小于父节点,右 子树大于父节点
二叉树与链表比较相似,在链表的基础上给内部类增加了两个节点
二叉树基本方法有增加节点,删除节点,返回节点,返回节点数量
二叉树的删除操作是理解的重中之重
二叉树有三种遍历操作:先序遍历,中序遍历,后序遍历。
二叉树的输出节点操作采用中序遍历,中序遍历使数据按从小到大的顺序依次输出。

二叉树—增加节点操作

二叉树增加节点从两方面考虑:

  1. 二叉树为空,将要增加节点直接设为根节点
  2. 二叉树已有节点,这里再分两种情况:
  3. 新增节点小于本次对比的数据。此时查看本次节点的左子树,若左子树为空,则将新增节点设为本次节点的左子树;若不为空,本次节点的左子树递归调用方法。
  4. 新增节点大于本次对比的数据。此时查看本次节点的右子树,若右子树为空,则将新增节点设为本次节点的右子树;若不为空,本次节点的右子树递归调用方法。

增加节点—代码实现:

class BinaryTree<T extends Comparable>{
	private class Node{
		private Comparable<T> data;
		private Node parent;           // 该节点的父节点
		private Node left;             // 该节点左子树的根节点
		private Node right;            // 该节点右子树的根节点
		public Node(Comparable<T> t) {
			this.data = t;
		}
		//判断数据大小,决定新增节点在该二叉树中的位置
		public void addNode(Node newNode) {
			if(this.data.compareTo((T)newNode.data)>0) {
				if(this.left == null) {
					this.left = newNode;
					this.left.parent = this;
				}else {
					this.left.addNode(newNode);
				}
			}else {
				if(this.right == null) {
					this.right = newNode;
					this.right.parent = this;
				}else {
					this.right.addNode(newNode);
				}
			}
		}
	}
	private Node root;       // 根节点
	private int count;       // 节点计数属性
	//二叉树为空,新增节点设为根节点,不为空则调用addNode方法实现增加操作
	public void add(Comparable<T> data) {
		if(data == null) {
			throw new NullPointerException("保存数据不允许为空");
		}
			Node newNode = new Node(data);
			if(this.root == null) {
				this.root = newNode;
			}else {
				this.root.addNode(newNode);
			}
			this.count++;
	}
}

二叉树—输出节点操作

二叉树的输出节点操作分两方面考虑:

  1. 二叉树为空,返回空值
  2. 二叉树不为空,中序遍历二叉树

何为中序遍历?三步操作:

  1. 查看当前节点有无左子树,有则遍历,没有则开始步骤二
  2. 当前节点无左子树,输出该节点,然后开始步骤三
  3. 查看当前节点有无右子树,有则开始步骤一,没有则输出上一节点并跳至步骤三

输出节点—代码实现(这里将增加节点的代码放在一起):

class BinaryTree<T extends Comparable>{
	private class Node{
		private Comparable<T> data;
		private Node parent;
		private Node left;
		private Node right;
		public Node(Comparable<T> t) {
			this.data = t;
		}
		public void addNode(Node newNode) {
			if(this.data.compareTo((T)newNode.data)>0) {
				if(this.left == null) {
					this.left = newNode;
					this.left.parent = this;
				}else {
					this.left.addNode(newNode);
				}
			}else {
				if(this.right == null) {
					this.right = newNode;
					this.right.parent = this;
				}else {
					this.right.addNode(newNode);
				}
			}
		}
		// 中序遍历
		public void toArrayNode() {
			if(this.left != null) {
				this.left.toArrayNode();
			}
			BinaryTree.this.returndata[BinaryTree.this.foot++] = this.data;
			if(this.right != null) {
				this.right.toArrayNode();
			}
		}
	}
	private Node root;
	private int count;
	private int foot = 0;
	private Object[] returndata;
	public void add(Comparable<T> data) {
		if(data == null) {
			throw new NullPointerException("保存数据不允许为空");
		}
			Node newNode = new Node(data);
			if(this.root == null) {
				this.root = newNode;
			}else {
				this.root.addNode(newNode);
			}
			this.count++;
	}
	//二叉树为空则返回null,不为空交给toArrayNode实现
	public Object[] toArray() {
		if(this.count == 0) {
			return null;
		}
		this.foot = 0;
		this.returndata = new Object[this.count];
		this.root.toArrayNode();
		return this.returndata;
	}
}

二叉树—删除节点操作

二叉树删除节点考虑三种情况:

  1. 待删除节点为叶子节点,断开该节点的父节点与它的联系
  2. 待删除节点只有一个子树,将该节点的父节点与其子树联系
  3. 待删除节点左右子树都存在,挑选该节点右子树的最小节点或左子树的最大节点,将其的数据赋值给该节点,并断开该节点的父节点与他的联系

删除节点(含增加节点,输出节点所有代码)—代码实现:

class BinaryTree<T extends Comparable>{
	private class Node{
		private Comparable<T> data;
		private Node parent;
		private Node left;
		private Node right;
		public Node(Comparable<T> t) {
			this.data = t;
		}
		public void addNode(Node newNode) {
			if(this.data.compareTo((T)newNode.data)>0) {
				if(this.left == null) {
					this.left = newNode;
					this.left.parent = this;
				}else {
					this.left.addNode(newNode);
				}
			}else {
				if(this.right == null) {
					this.right = newNode;
					this.right.parent = this;
				}else {
					this.right.addNode(newNode);
				}
			}
		}
		public void toArrayNode() {
			if(this.left != null) {
				this.left.toArrayNode();
			}
			BinaryTree.this.returndata[BinaryTree.this.foot++] = this.data;
			if(this.right != null) {
				this.right.toArrayNode();
			}
		}
		public Node getremoveNode(Comparable<T> data) {
			if(this.data.compareTo((T)data) == 0) {
				return this;
			}
			if(this.data.compareTo((T)data) > 0) {
					if(this.left != null) {
						return this.left.getremoveNode(data);
					}else {
						return null;
					}
			}else {
				if(this.right != null) {
					return this.right.getremoveNode(data);
				}else {
					return null;
				}
			}
		}
	}
	private Node root;
	private int count;
	private int foot = 0;
	private Object[] returndata;
	public void add(Comparable<T> data) {
		if(data == null) {
			throw new NullPointerException("保存数据不允许为空");
		}
			Node newNode = new Node(data);
			if(this.root == null) {
				this.root = newNode;
			}else {
				this.root.addNode(newNode);
			}
			this.count++;
	}
	public Object[] toArray() {
		if(this.count == 0) {
			return null;
		}
		this.foot = 0;
		this.returndata = new Object[this.count];
		this.root.toArrayNode();
		return this.returndata;
	}
	//由getremoveNode方法找到待删除节点,再依据上面我说的三种情况分别处理
	public void remove(Comparable<T> data) {
		Node removeNode = this.root.getremoveNode(data);
		if(removeNode == null) {
			System.out.println("不存在");
		}
		if(this.root.data.compareTo((T)data) == 0) {
			Node moveNode = this.root.right;
			while(moveNode.left != null) {
				moveNode = moveNode.left;
			}
			moveNode.parent.left = null;
			this.root.data = moveNode.data;
		}else if(removeNode.left == null && removeNode.right == null){	
			if(removeNode.parent.left.data == removeNode.data) {
				removeNode.parent.left = null;
			}else {
				removeNode.parent.right = null;
			}
		}else if(removeNode.left != null && removeNode.right == null) {
			removeNode.parent.left = removeNode.left;
			removeNode.left.parent = removeNode.parent;
		}else if(removeNode.right != null && removeNode.left == null) {
			removeNode.parent.left = removeNode.right;
			removeNode.right.parent = removeNode.parent;
		}else {
			Node moveNode = removeNode.right;
			while(moveNode.left != null) {
				moveNode = moveNode.left;
			}
			removeNode.data = moveNode.data;
			moveNode.parent.left = null;

		}
		this.count--;
	}
}

二叉树—返回节点数操作

二叉树的返回节点操作,如果还有印象我们设置了节点计数属性,return返回该属性即可。

猜你喜欢

转载自blog.csdn.net/weixin_44078014/article/details/105601845