二叉树的实现

定义一个类,用来当做二叉树的节点,也可以用内部类

package dateStructure;

public class TNode {
	public int date;
	public TNode leftChild;
	public TNode rightChild;
	
	public TNode(int key) {
		this.date = key;
	}
}

下面是二叉树的实现:比较难的是删除,仔细琢磨。

package dateStructure;

public class IThree {

	TNode root = null;
	/**
	 * 查找节点
	 * 
	 * 查找节点的时间取决于这个节点所在的层数, 每一层最多有2n-1个节点,总共N层共有2n-1个节点, 那么时间复杂度为O(logN),底数为2,
	 * N表示的是二叉树节点的总数,而不是层数
	 * 
	 * @param key
	 * @return
	 */
	public TNode find(int key) {
		TNode temp = root;
		while (temp != null) {
			if (key > temp.date) {
				temp = temp.rightChild;
			} else if (key < temp.date) {
				temp = temp.leftChild;
			} else {
				return temp;
			}
		}
		return null;
	}

	/**
	 * 插入新节点
	 * 
	 * 要插入节点,必须先找到插入的位置。 与查找操作相似,由于二叉搜索树的特殊性, 待插入的节点也需要从根节点开始进行比较,
	 * 小于根节点则与根节点左子树比较,反之则与右子树比较, 直到左子树为空或右子树为空,则插入到相应为空的位置, 在比较的过程中要注意保存父节点的信息 及
	 * 待插入的位置是父节点的左子树还是右子树,才能插入到正确的位置。
	 * 
	 * @param key
	 * @return
	 */
	public boolean insert(int key) {
		TNode newNode = new TNode(key);
		if (root == null) {
			root = newNode;
			return true;
		}
		TNode preNode = null;
		TNode temp = root;
		while (temp != null) {
			preNode = temp;
			if (key > temp.date) {
				temp = temp.rightChild;
				if (temp == null) {
					preNode.rightChild = newNode;
					return true;
				}
			} else {
				temp = temp.leftChild;
				if (temp == null) {
					preNode.leftChild = newNode;
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 遍历二叉树
	 * 
	 * @param key
	 * @return
	 */
	// 先序遍历
	public void infixOrder(TNode current) {
		if (current != null) {
			System.out.print(current.date + "    ");
			infixOrder(current.leftChild);
			infixOrder(current.rightChild);
		}
	}

	// 中序遍历
	public void preOrder(TNode current) {
		if (current != null) {
			preOrder(current.leftChild);
			System.out.print(current.date + "    ");
			preOrder(current.rightChild);
		}
	}

	// 后序遍历
	public void postOrder(TNode current) {
		if (current != null) {
			postOrder(current.leftChild);
			postOrder(current.rightChild);
			System.out.print(current.date + "    ");
		}
	}

	/**
	 * 查找最值
	 * 
	 * 要找最小值,先找根的左节点, 然后一直找这个左节点的左节点, 直到找到没有左节点的节点,那么这个节点就是最小值。 同理要找最大值,一直找根节点的右节点,
	 * 直到没有右节点,则就是最大值
	 * 
	 * @return
	 */
	// 查找最大值
	public TNode findMax() {
		TNode preNode = null;
		TNode temp = root;
		if (root != null) {
			while (temp != null) {
				preNode = temp;
				temp = temp.rightChild;
			}
		}
		return preNode;
	}

	// 查找最小值
	public TNode findMin() {
		TNode preNode = null;
		TNode temp = root;
		if (root != null) {
			while (temp != null) {
				preNode = temp;
				temp = temp.leftChild;
			}
		}
		return preNode;
	}

	/**
	 * 删除节点 删除节点是二叉搜索树中最复杂的操作,
	 *  删除的节点有三种情况,前两种比较简单,但是第三种却很复杂。 
	 *  1、该节点是叶节点(没有子节点)
	 * 2、该节点有一个子节点
	 *  3、该节点有两个子节点
	 */
	public boolean delete(int key) {
		TNode preNode = root;
		TNode nextNode = root;
		while (nextNode.date != key) {
			preNode = nextNode;
			if (key < nextNode.date) {
				nextNode = nextNode.leftChild;
			} else {
				nextNode = nextNode.rightChild;
			}
			if (nextNode == null) {
				return false;
			}
		}
		 //该节点是叶子结点 
		if (nextNode.leftChild == null && nextNode.rightChild == null) {
			// 如果该叶子结点是根节点
			if (nextNode == root)
				root = null;
			// 不是根结点
			if (preNode.leftChild == nextNode) {
				preNode.leftChild = null;
			} else {
				preNode.rightChild = null;
			}
			return true;
		//该节点只有右结点
		}else if (nextNode.leftChild == null && nextNode.rightChild != null) {
			if(nextNode == root)
				root = nextNode.rightChild;
			if(preNode.rightChild == nextNode) {
				preNode.rightChild = nextNode.rightChild;
			}else {
				preNode.leftChild = nextNode.rightChild;
			}
			return true;
		//该节点只有左节点
		}else if(nextNode.leftChild != null && nextNode.rightChild == null) {
			if(nextNode == root)
				root = nextNode.leftChild;
			if(preNode.rightChild == nextNode) {
				preNode.rightChild = nextNode.leftChild;
			}else {
				preNode.leftChild = nextNode.leftChild;
			}
			return true;
		//该节点有两个子节点
		}else {
			TNode successor = getSuccessor(nextNode);
			if(nextNode == root)
				root = successor;
			if(preNode.leftChild == nextNode) {
				preNode.leftChild = successor;
			}else {
				preNode.rightChild = successor;
			}
			successor.leftChild = nextNode.leftChild;
			return true;
		}
	}
	//找到删除节点的中序后继元素
	 public TNode getSuccessor(TNode delNode){
	        TNode successorParent = delNode;
	        TNode successor = delNode;
	        TNode current = delNode.rightChild;
	        while(current != null){
	            successorParent = successor;
	            successor = current;
	            current = current.leftChild;
	        }
	        //后继节点不是删除节点的右子节点,将后继节点替换删除节点
	        if(successor != delNode.rightChild){
	            successorParent.leftChild = successor.rightChild;
	            successor.rightChild = delNode.rightChild;
	        }
	        return successor;
	    }
	// Other Method......

	public static void main(String[] args) {
		IThree th = new IThree();
		th.insert(4);
		th.insert(2);
		th.insert(1);
		th.insert(3);
		th.insert(6);
		th.insert(5);
		th.insert(7);
		th.insert(8);
		th.insert(0);
		
		System.out.println(th.find(3).date);

		System.out.print("先序遍历:");
		th.infixOrder(th.root);
		System.out.println();

		System.out.print("中序遍历:");
		th.preOrder(th.root);
		System.out.println();

		System.out.print("后序遍历:");
		th.postOrder(th.root);
		System.out.println();

		System.out.println("最大值:" + th.findMax().date);
		System.out.println("最小值:" + th.findMin().date);

		System.out.println(th.delete(6));
		
		System.out.print("中序遍历:");
		th.preOrder(th.root);
		System.out.println();
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yelvens

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值