java数据结构与算法--04树

package p30;

public class Hq_P30 {
	

	public TreeNode root;

	public Hq_P30(TreeNode root) {
		this.root = root;
	}

	public Hq_P30() {
	}

	/**
	 * 创建查找二叉树,添加结点
	 * 
	 * @author worm
	 *
	 */

	public TreeNode put(int data) {

		TreeNode node = null;
		TreeNode parent = null;// 当前要添加进去的,记录父节点

		if (root == null) {// 说明没有根结点
			node = new TreeNode(0, data);// 创建根节点
			root = node;
			return node;
		}
		/*
		 * 如果有root结点 新来的结点要去从顶点开始入比较, 如果比顶点小 ,则在左边再去比比较 如果比顶点大 则 去右边再去比比较 直到
		 * 比较的当前元素没有子节点 则创建新的结点
		 */
		node = root;// 从最顶点开始取比较
		while (node != null) {// 直到 比较的当前元素没有子节点 则创建新的结点
			// node为空时 找到地方添加新的data
			parent = node;// 记录父节点 把当前的比较点作为父节点
			if (data > node.data) {// 大于当前结点,则data在在右边进行比较,往右边走
				node = node.RightChild;// 往右半边走
			} else if (data < node.data) {
				node = node.LeftChild;// 当data<当前结点时
			} else {// data 等于 当前结点
				return node;
			}
		}
		// 表示将data添加到相应中结点中去
		// node 代表 node当前的位置正是 data该放的位置
		node = new TreeNode(0, data);
		if (data < parent.data) {// 双向 node可以找到 parent 也可以找到自己的孩纸
			parent.LeftChild = node;
			node.parent = node;
		} else{
			parent.RightChild = node;
			node.parent = parent;
		}
		return node;
	}

	/**
	 * 删除一个结点: 1 、判断叶子结点 直接 为null 2、如果要删除的元素只有一个孩子结点 则当前结点的还在结点的下一个子节点为当前结点的孩子结点 --
	 * 3、 如果有两个孩子结点 则找到左半边的 右边边最大的 或者右孩子的最 左边的的叶子结点 作为当前删除 元素的那个结点的替补 ---一个函数的后继结点??
	 * 
	 * @param node
	 */
	public TreeNode del(TreeNode node, int key) {
		TreeNode sNode = searchNode(node, key);
		if (sNode == null) {
			return node;
		}else if (sNode.LeftChild == null && sNode.RightChild == null) {// 删除的为叶子结点
			if (sNode.parent.LeftChild.data == key) {// 如果要删除左孩纸结点
				sNode.parent.LeftChild = null;
			} else {
				sNode.parent.RightChild = null;// 如果删除的是右叶子结点
			}
			return node;
		} else if (sNode.LeftChild != null || sNode.RightChild != null) {// 如果不为叶子结点
			if (sNode.LeftChild != null && sNode.RightChild == null) {// 如果删除的为只有一个孩纸的父节点
				if (sNode.parent.LeftChild.data == key) {// sNode为父节点的左结点
					sNode.parent.LeftChild = sNode.LeftChild;
					sNode.LeftChild.parent = sNode.parent;
				} else {
					sNode.parent.RightChild = sNode.LeftChild;
					sNode.LeftChild.parent = sNode.parent;
				}
				return node;
			} else if (sNode.LeftChild == null && sNode.RightChild != null) {
				if (sNode.parent.LeftChild.data == key) {// sNode为父节点的左结点
					sNode.parent.LeftChild = sNode.RightChild;
					sNode.RightChild.parent = sNode.parent;
				} else {
					sNode.parent.RightChild = sNode.RightChild;
					sNode.RightChild.parent = sNode.parent;
				}
				return node;
			} else {// 如果孩子结点不为一个
					// 找到左边孩子的 遍历到 它的最右边的节点 作为当前删除结点存放的位置
				TreeNode tempNode = sNode.LeftChild;// 可替代的叶子结点
				while (tempNode != null) {// 一直循环找到最下面的叶子结点
					tempNode = tempNode.RightChild;
				}
				if (sNode.parent.LeftChild.data == key) {// 带有至少两个结点的 删除元素为父节点的左孩子
					tempNode.parent.RightChild = null;
					sNode.parent.LeftChild = tempNode;
					tempNode.LeftChild = sNode.LeftChild;
					tempNode.parent = sNode.parent;

				} else {
					tempNode.parent.RightChild = null;
					sNode.parent.RightChild = tempNode;
					tempNode.LeftChild = sNode.LeftChild;
					tempNode.parent = sNode.parent;
				}
				return node;
			}

		}
		return node;
	}

	public TreeNode searchNode(TreeNode node, int key) {// 寻找key值得 对应的node

		if (node == null) {
			return null;
		}

		while (node != null) {
			if (key > node.data) {// 大于当前结点,则data在在右边进行比较,往右边走
				node = node.RightChild;// 往右半边走
			} else if (key < node.data) {
				node = node.LeftChild;// 当data<当前结点时
			}else {
				return node;
			}
		}
		return null;
	}

	public void minOrder(TreeNode node) {
		if (node == null) {
			return;
		} else {
			minOrder(node.LeftChild);
			System.out.print(node.data + "  ");
			minOrder(node.RightChild);
		}

	}

	class TreeNode {// 内部类
		private int index;
		private int data;
		private TreeNode LeftChild;
		private TreeNode RightChild;
		private TreeNode parent;

		public int getIndex() {
			return index;
		}

		public void setIndex(int index) {
			this.index = index;
		}

		public int getData() {
			return data;
		}

		public void setData(int data) {
			this.data = data;
		}

		public TreeNode getLeftChild() {
			return LeftChild;
		}

		public void setLeftChild(TreeNode leftChild) {
			LeftChild = leftChild;
		}

		public TreeNode getRightChild() {
			return RightChild;
		}

		public void setRightChild(TreeNode rightChild) {
			RightChild = rightChild;
		}

		public TreeNode getParent() {
			return parent;
		}

		public void setParent(TreeNode parent) {
			this.parent = parent;
		}

		public TreeNode(int index, int data) {
			super();
			this.index = index;
			this.data = data;
			this.LeftChild = null;
			this.parent = null;
			this.RightChild = null;
		}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值