数据结构知识整理(二)——二叉搜索树

来源:互联网 发布:中控考勤机上传数据 编辑:程序博客网 时间:2024/05/07 16:29

树是一种特殊的数据结构,使用它可以既获得像链表一样的插入、删除速度,还可以像有序数组一样快速查找。二叉树是树中的一中,他的各个节点最多只能有两个子结点(左子结点、右子结点),而二叉搜索树还有另外一个特征,即他的一个节点的左子结点的关键值小于这个节点,右子结点的关键值大于这个结点。

二叉搜索树的操作有查找、插入、删除、遍历等。

实现

树节点

public class TreeNode {int data;TreeNode leftChild;TreeNode rightChild;public TreeNode(int value) {data = value;}public void displayNode() {System.out.println("data->" + data);}}

public class Tree {private TreeNode root;public Tree() {root = null;}public boolean find(int value) {TreeNode current = root;if(current == null) {return false;}while(current.data != value) {if(current.data < value) {current = current.leftChild;} else {current = current.rightChild;}if(current == null) {return false;}}return true;}public void insert(int value) {TreeNode node = new TreeNode(value);if(root == null) {root = node;} else {TreeNode current = root;while(true) {if(value <= current.data) {if(current.leftChild == null) {current.leftChild = node;break;} else {current = current.leftChild;}} else if(value > current.data) {if(current.rightChild == null) {current.rightChild = node;break;} else {current = current.rightChild;}}}}}public boolean delet(int value) {TreeNode current = root;TreeNode parent = null;boolean isLeft = false;if(current == null) {return false;}while(current.data != value) {parent = current;if(value < current.data) {current = current.leftChild;isLeft = true;} else {current = current.rightChild;isLeft = false;}if(current == null) {return false;}}if(current.leftChild == null && current.rightChild == null) {//没有子结点的情况if(current == root) { root = null; }else if(isLeft) { parent.leftChild = null; }else { parent.rightChild = null; }} else if(current.leftChild == null) {//没有右子结点的情况if(current == root) { root = root.rightChild; }else if(isLeft) { parent.leftChild = current.rightChild; }else { parent.rightChild = current.rightChild; }} else if(current.rightChild == null) {//没有左子结点的情况if(current == root) { root = root.leftChild; }else if(isLeft) { parent.leftChild = current.leftChild; }else { parent.rightChild = current.rightChild; }} else {//两个结点都存在的情况TreeNode successor = getSuccessor(current);if(current == root) { root = successor; } else if(isLeft) { parent.leftChild = successor; } else { parent.rightChild = successor; }successor.leftChild = current.leftChild;}return true;}//寻找后继结点private TreeNode getSuccessor(TreeNode node) {TreeNode successor = node;TreeNode current = node.rightChild;while(current.leftChild != null) {successor = current;current = current.leftChild;}if(successor != node) {successor.leftChild = current.rightChild;current.rightChild = node.rightChild;}return current;}public void displayTree() {preOrder(root);}private void preOrder(TreeNode node) {//前序遍历if(node != null) {node.displayNode();preOrder(node.leftChild);preOrder(node.rightChild);}}}

在实现上二叉搜索树要比栈、队列、链表复杂,因为树的结构不再是线性的。

二叉搜索树的方法中最复杂的是删除操作,因为删除节点的时候有三种基本的情况:

1、没有子结点;2、有一个子结点;3,有两个子结点。

同时因为二叉搜索树规定了左子结点小于父结点,右子结点大于父结点,因此当删除一个节点时,如果他含有子结点,那么就需要在自己点中寻找一个自己的后继结点(所有比自己大的节点中最小的那个)来替代自己的结点位置。



原创粉丝点击