java二叉树的删除_二叉树删除操作(java)

二叉树最复杂的步骤即为删除操作,此处只简单介绍一下具体思路:

(1)如果待删除的节点是一片树叶,那么它可以被立即删除。然后将其父节点的相应子节点(左节点或右节点)至空。

(2)如果被删除的节点有一个子节点,那么把它的子节点直接连到它的父节点上即可。(Node:current,parent)

(3)如果被删除的节点(a)有两个子节点,就不能简单的用它的一个子节点代替它。一般找到(a)的右子树中key最小的节点(c)代替它,如果c不为叶子节点,那么递归对c进行相应的删除操作。(Node:successorParent,successor,current)

package com.donghao.erchashu;

public class Node {

public int iData;

public Node leftChild;

public Node rightChild;

public void displayNode(){

System.out.println('{' + iData + ',' + '}');

}

}

package com.donghao.erchashu;

public class Tree {

private Node root;

public Tree() {

root = null;

}

public Node find(int key) {

Node current = root;

while (current.iData != key) {

if (key < current.iData) {

current = current.leftChild;

} else {

current = current.rightChild;

}

if (current == null)

return null;

}

return current;

}

public void insert(int id) {

Node newNode = new Node();

newNode.iData = id;

if (root == null)

root = newNode;

else {

Node current = root;

Node parent;

while (true) {

parent = current;

if (id < current.iData) {

current = current.leftChild;

if (current == null) {

parent.leftChild = newNode;

return;

}

} else {

current = current.rightChild;

if (current == null) {

parent.rightChild = newNode;

return;

}

}

}

}

}

public boolean delete(int key) {

Node current = root;

Node parent = root;

boolean isLeftChild = true;

while (current.iData != key) {

parent = current;

if (key < current.iData) {

isLeftChild = true;

current = current.leftChild;

} else {

isLeftChild = false;

current = current.rightChild;

}

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;

// 只有一个子节点

} else if (current.rightChild == null) {

if (current == root)

root = current.leftChild;

else if (isLeftChild)

parent.leftChild = current.leftChild;

else

parent.rightChild = current.leftChild;

} else if (current.leftChild == null) {

if (current == root)

root = current.rightChild;

else if (isLeftChild)

parent.leftChild = current.rightChild;

else

parent.rightChild = current.rightChild;

}

// 两个子节点

else {

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;

}

private Node getSuccessor(Node delNode) {

Node successorParent = delNode;

Node successor = delNode;

Node 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;

}

}

重点解释:

getSuccessor方法找到a的直接后继c(即以a的右节点为根的子树中的最左孩子)

<1>如果c为a的右节点:步骤一:将a的parent.rightChild置换为c

步骤二:将c的左子树置换为a的parent.leftChild

<2>如果c为a的右节点的左后代:步骤一:将c的parent.leftChild置换为c.rightChild(getSuccessor()方法中实现)

步骤二:将c的rightChild置换为a的parent.rightChild(getSuccessor()方法中实现)

步骤三:将a(即current节点)的parent.rightChild置换为c节点

步骤四:将最新的a节点(已被c置换掉)的leftChild置换为原a节点的左孩子(current.leftChild)

构建二叉树的算法可以使用递归或迭代的方式实现。 以下是使用递归方式构建二叉树的示例代码: ``` class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BinaryTree { public TreeNode buildTree(int[] preorder, int[] inorder) { if (preorder == null || inorder == null || preorder.length != inorder.length) { return null; } return buildTreeHelper(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1); } private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) { if (preStart > preEnd || inStart > inEnd) { return null; } int rootVal = preorder[preStart]; int rootIndex = 0; for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == rootVal) { rootIndex = i; break; } } int leftSize = rootIndex - inStart; TreeNode root = new TreeNode(rootVal); root.left = buildTreeHelper(preorder, inorder, preStart + 1, preStart + leftSize, inStart, rootIndex - 1); root.right = buildTreeHelper(preorder, inorder, preStart + leftSize + 1, preEnd, rootIndex + 1, inEnd); return root; } } ``` 以上代码中,`buildTree`方法接受两个数组,一个是先序遍历序列,一个是中序遍历序列。通过先序遍历序列的第一个节点确定根节点,在中序遍历序列中找到根节点的位置,根节点左边的节点为左子,右边的节点为右子。递归调用`buildTreeHelper`方法建立左右子,并将其连接到根节点上。 以下是使用迭代方式构建二叉树的示例代码: ``` class TreeNode { int val; TreeNode left; TreeNode right; TreeNode(int x) { val = x; } } public class BinaryTree { public TreeNode buildTree(int[] preorder, int[] inorder) { if (preorder == null || inorder == null || preorder.length != inorder.length) { return null; } Stack<TreeNode> stack = new Stack<>(); TreeNode root = new TreeNode(preorder[0]); stack.push(root); int inorderIndex = 0; for (int i = 1; i < preorder.length; i++) { TreeNode node = stack.peek(); if (node.val != inorder[inorderIndex]) { node.left = new TreeNode(preorder[i]); stack.push(node.left); } else { while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) { node = stack.pop(); inorderIndex++; } node.right = new TreeNode(preorder[i]); stack.push(node.right); } } return root; } } ``` 以上代码中,使用栈来辅助构建二叉树。先将先序遍历序列的第一个节点作为根节点入栈,然后依次遍历先序遍历序列中的每个节点,如果当前节点不等于中序遍历序列中的节点,则表示当前节点是根节点的左子,将其作为左子节点入栈;否则,不断弹出栈顶元素,直到栈顶元素等于中序遍历序列中的节点,表示当前节点是某个节点的右子,将其作为右子节点入栈。最终返回根节点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值