Tree的遍历与node定义学习


/*
 * 二叉树节点
 */
public class Node {
	//数据项
	public long data;

	//左子节点
	public Node leftChild;
	//右子节点
	public Node rightChild;
	
	/**
	 * 构造方法
	 * @param data
	 */
	public Node(long data) {
		this.data = data;
	}
	
}

/*
 * 二叉树
 */
public class Tree {
	//根节点
	public Node root;
	
	/**
	 * 插入节点
	 * @param value
	 */
	public void insert(long value,String sValue) {
		//封装节点
		Node newNode = new Node(value);
		//引用当前节点
		Node current = root;
		//引用父节点
		Node parent;
		//如果root为null,也就是第一插入的时候
		if(root == null) {
			root = newNode;
			return;
		} else {
			while(true) {
				//父节点指向当前节点
				parent = current;
				//如果当前指向的节点数据比插入的要大,则向左走
				if(current.data > value) {
					current = current.leftChild;
					if(current == null) {
						parent.leftChild = newNode;
						return;
					}
				} else {
					current = current.rightChild;
					if(current == null) {
						parent.rightChild = newNode;
						return;
					}
				}
			}
		}
	}
	
	/**
	 * 查找节点
	 * @param value
	 */
	public Node find(long value) {
		//引用当前节点,从根节点开始
		Node current = root;
		//循环,只要查找值不等于当前节点的数据项
		while(current.data != value) {
			//进行比较,比较查找值和当前节点的大小
			if(current.data > value) {
				current = current.leftChild;
			} else {
				current = current.rightChild;
			}
			//如果查找不到
			if(current == null) {
				return null;
			}
		}
		return current;
	}

/**
	 * 删除节点  删除节点需要父子两层指针
	 * @param value
	 */
	public boolean delete(long value) {
		//引用当前节点,从根节点开始
		Node current = root;
		
		//应用当前节点的父节点
		Node parent = root;
		//是否为左节点
		boolean isLeftChild = true;
		
		while(current.data != value) {
			parent = current;
			//进行比较,比较查找值和当前节点的大小
			if(current.data > value) {
				current = current.leftChild;
				isLeftChild = true;
			} else {
				current = current.rightChild;
				isLeftChild = false;
			}
			//如果查找不到
			if(current == null) {
				return false;
			}
		}
		
		//删除叶子节点,也就是该节点没有子节点
		if(current.leftChild == null && current.rightChild == null) {
			if(current == root) {
				root = null;
			} else if(isLeftChild) {
				parent.leftChild = null;
			} else {
				parent.rightChild = null;
			}
		//current的右节点空,判断current是parrent的左孩子?右孩子?决定current的leftchild插入位置
		} else if(current.rightChild == null) {
			if(current == root) {
				root = current.leftChild;
			}else if(isLeftChild) {
				parent.leftChild = current.leftChild;
			} else {
				//是右节点,比parent节点要大
				parent.rightChild = current.leftChild;
			}
			//current只有右孩子的情况,其次判断current是parent的左右孩子,判断插入parent的位置
		} else if(current.leftChild == null) {
			if(current == root) {
				root = current.rightChild;
			} else if(isLeftChild) {//current是parent的左孩子
				parent.leftChild = current.rightChild;
			} else {//current是parent的右孩子
				parent.rightChild = current.rightChild;
			}
		} else {//current既有左孩子,也有右孩子
			Node successor = getSuccessor(current);
			// 先处理删除节点的父
			if(current == root) {
				root = successor;
			} else if(isLeftChild) {
				parent.leftChild = successor;
			} else{
				parent.rightChild = successor;
			}
			// 处理删除节点的左节点
			successor.leftChild = current.leftChild;
		}
		
		return true;
		
		
	}
	
	public Node getSuccessor(Node delNode) {
		Node successor = delNode;
		Node successorParent = delNode;
		Node current = delNode.rightChild;
		//寻找右子树的最左侧节点,比被删除节点稍微大一点
		while(current != null) {
			successorParent = successor;
			successor = current;
			current = current.leftChild; // 删除节点的右子树的最左侧孩子节点
		}
		//被删除的右孩子,不等于找到的最左侧节点,successor就是右子树的最左侧孩子,successorParent是父节点
		//不等于就是找到了,
		if(successor != delNode.rightChild) {
			//将最左节点的右节点给父节点是左,比较小,所以放再left
			successorParent.leftChild = successor.rightChild;
			// 直接放到位置了
			successor.rightChild = delNode.rightChild;
		}
		return successor;
	}
	




	
	/**
	 * 前序遍历
	 */
	public void frontOrder(Node localNode) {
		if(localNode != null) {
			//访问根节点
			System.out.println(localNode.data + " ");
			//前序遍历左子树
			frontOrder(localNode.leftChild);
			//前序遍历右子树
			frontOrder(localNode.rightChild);
		}
	}
	
	/**
	 * 中序遍历
	 */
	public void inOrder(Node localNode) {
		if(localNode != null) {
			//中序遍历左子树
			inOrder(localNode.leftChild);
			//访问根节点
			System.out.println(localNode.data + " ");
			//中旬遍历右子树
			inOrder(localNode.rightChild);
		}
	}
	
	/**
	 * 后序遍历
	 */
	public void afterOrder(Node localNode) {
		if(localNode != null) {
			//后序遍历左子树
			afterOrder(localNode.leftChild);
			//后序遍历右子树
			afterOrder(localNode.rightChild);
			//访问根节点
			System.out.println(localNode.data + " " );
		}
	}
}

posted @ 2021-12-15 16:09  堕落先锋  阅读(197)  评论(0编辑  收藏  举报