二叉查找树的各种操作(插入、删除、查找、遍历)
来源:互联网 发布:sql updata 编辑:程序博客网 时间:2024/06/05 08:36
二叉查找树主要的特点:当前节点左边的所有节点要小于该节点,右边的要大于该节点。(不能只判断当前节点的左儿子和右儿子是否小于或大于当前节点)
下面是对二叉查找树的各种操作列表
1. 插入(递归、非递归)
2. 删除
3. 查找最小值、最大值
4. 先序遍历(递归,非递归)
5. 中序遍历(递归,非递归)
6. 后序遍历(递归,非递归)
7. 层次遍历
8. 检查二叉树是否二叉查找树(时间复杂度O(nlogn)和O(n))
节点类代码:
import java.util.Queue;import java.util.Stack;import java.util.concurrent.LinkedBlockingDeque;/** * * @author fx50jk * @param <T> */class BinaryTree<Key extends Comparable<Key>, T> { TreeNode root; public class TreeNode { public TreeNode leftchild; public TreeNode rightchild; public Key key; public T data; public boolean visited = false; public TreeNode() { } public TreeNode(Key key, T data) { this.key = key; this.data = data; } public TreeNode(T data, TreeNode leftchild, TreeNode rightchild) { this.leftchild = leftchild; this.rightchild = rightchild; this.data = data; } } public BinaryTree(TreeNode root) { this.root = root; } public BinaryTree() { } public void insert1(Key key) { if (key == null) { System.out.println("???"); } else { root = insert1(root, key); } } private TreeNode insert1(TreeNode rootNode, Key key) { if (rootNode == null) { rootNode = new TreeNode(); rootNode.key = key; } //插入左子树还是右子树 int comRes = key.compareTo(rootNode.key); if (comRes < 0) { rootNode.leftchild = insert1(rootNode.leftchild, key); } else if (comRes > 0) { rootNode.rightchild = insert1(rootNode.rightchild, key); } else { //已经有该数据 System.out.println("键值重复"); } return rootNode; } public void insert(Key key, T value) { if (root == null) { root = new TreeNode(key, value); return; } TreeNode currentNode = root; TreeNode parentNode = root; boolean isLeftChild = true; while (currentNode != null) { parentNode = currentNode;//保存父节点的信息 //判断它是左节点还是右节点 int comRes = key.compareTo(currentNode.key); if (comRes < 0) { currentNode = currentNode.leftchild; isLeftChild = true; } else { currentNode = currentNode.rightchild; isLeftChild = false; } } TreeNode newNode = new TreeNode(key, value); if (isLeftChild) { parentNode.leftchild = newNode; } else { parentNode.rightchild = newNode; } } //根据key删除节点 public void remove(Key key){ root=remove(root,key); } private TreeNode remove(TreeNode rootNode,Key key){ if (rootNode==null) { return rootNode; } int comRes=key.compareTo(rootNode.key); if (comRes<0) { rootNode.leftchild=remove(rootNode.leftchild, key); }else if(comRes>0){ rootNode.rightchild=remove(rootNode.rightchild, key); }else if(rootNode.leftchild!=null&&rootNode.rightchild!=null){//已找到该节点,开始进行删除 rootNode.key=findMin(rootNode.rightchild).key; rootNode.rightchild=remove(rootNode.rightchild, key); }else{ rootNode=(rootNode.leftchild!=null)?rootNode.leftchild:rootNode.rightchild; } return rootNode; } //查找最小值 public Key findMin(){ if (root==null) { return null; } return findMin(root).key; } private TreeNode findMin(TreeNode rootNode){ if (rootNode==null) { return null; }else if(rootNode.leftchild==null){//从左子树中找最左的节点 return rootNode; }else{ return findMin(rootNode.leftchild); } } //查找最大值 public Key findMax(){ if (root==null) { return null; } return findMax(root).key; } private TreeNode findMax(TreeNode rootNode){ if (rootNode==null) { return null; }else if(rootNode.rightchild==null){//从右子树中找最右的节点 return rootNode; }else{ return findMin(rootNode.rightchild); } } //遍历的递归实现 //先序遍历 public void preOrder() { preOrder(root); System.out.println(""); } private void preOrder(TreeNode treeNode) { if (treeNode != null) { System.out.print(treeNode.key + "\t"); preOrder(treeNode.leftchild); preOrder(treeNode.rightchild); } } //中序遍历 public void midOrder() { midOrder(root); System.out.println(""); } private void midOrder(TreeNode treeNode) { if (treeNode != null) { midOrder(treeNode.leftchild); System.out.print(treeNode.key + "\t"); midOrder(treeNode.rightchild); } } //后序遍历 public void postOrder() { postOrder(root); } private void postOrder(TreeNode treeNode) { if (treeNode != null) { postOrder(treeNode.leftchild); postOrder(treeNode.rightchild); System.out.print(treeNode.key + "\t"); } } //遍历的非递归实现 public void preOrderTraverse() { Stack<TreeNode> stack = new Stack<>(); TreeNode rootNode = root; if (rootNode != null) { stack.push(rootNode); while (!stack.isEmpty()) { rootNode = stack.pop(); System.out.print(rootNode.key + "\t"); if (rootNode.rightchild != null) { stack.push(rootNode.rightchild); } if (rootNode.leftchild != null) { stack.push(rootNode.leftchild); } } } System.out.println(""); } public void inOrderTraverse() { Stack<TreeNode> stack = new Stack<>(); TreeNode rootNode = root; while (rootNode != null) { while (rootNode != null) { if (rootNode.rightchild != null) { stack.push(rootNode.rightchild);//先让右节点入栈 } stack.push(rootNode);//让中间节点入栈 rootNode = rootNode.leftchild; } rootNode = stack.pop(); while (!stack.isEmpty() && rootNode.rightchild == null) { System.out.print(rootNode.key + "\t"); rootNode = stack.pop(); } System.out.print(rootNode.key + "\t"); if (!stack.empty()) { rootNode = stack.pop(); } else { rootNode = null; } } System.out.println(""); } public void postOrderTraverse() { TreeNode rootNode = root; TreeNode temp = root; Stack<TreeNode> stack = new Stack<>(); while (rootNode != null) { //左子树入栈 while (rootNode.leftchild != null) { stack.push(rootNode); rootNode = rootNode.leftchild; } // 当前结点无右子结点或右子结点已经输出 while (rootNode != null && (rootNode.rightchild == null || rootNode.rightchild == temp)) { System.out.print(rootNode.key + "\t"); temp = rootNode; if (stack.isEmpty()) { return; } rootNode = stack.pop(); } //处理右节点 stack.push(rootNode); rootNode = rootNode.rightchild; } System.out.println(""); } public void levelOrder() { /** * 存放需要遍历的结点,左结点一定优先右节点遍历 */ Queue<TreeNode> queue = new LinkedBlockingDeque<>(); TreeNode rootNode = this.root; while (rootNode != null) { //记录经过的结点 System.out.print(rootNode.key + "\t"); //先按层次遍历结点,左结点一定在右结点之前访问 if (rootNode.leftchild != null) { //孩子结点入队 queue.add(rootNode.leftchild); } if (rootNode.rightchild != null) { queue.add(rootNode.rightchild); } //访问下一个结点 rootNode = queue.poll(); } } //检查二叉树是否是二叉查找树 时间复杂度为O(NlogN) public boolean isBalanced(){ return isBalanced(root); } private boolean isBalanced(TreeNode rootNode){ if (rootNode==null) { return true; } int heightDiff=getHeight(rootNode.leftchild)-getHeight(rootNode.rightchild); if (Math.abs(heightDiff)>1) { return false; }else{ return isBalanced(rootNode.leftchild)&&isBalanced(rootNode.rightchild); } } public int getHeight(TreeNode rootNode){ if(rootNode==null){ return 0; } return Math.max(getHeight(rootNode.leftchild), getHeight(rootNode.rightchild))+1; } //判断是否平衡 时间复杂度为O(n) private int checkHeight(TreeNode rootNode){ if (rootNode==null) { return 0; } //检查左子树是否平衡 int leftHeight=checkHeight(rootNode.leftchild); if (leftHeight==-1) { return -1; } //检查右子树 int rightHeight=checkHeight(rootNode.rightchild); if (rightHeight==-1) { return -1; } //检查当前节点是否平衡 int heightDiff=Math.abs(leftHeight-rightHeight); if (heightDiff>1) { return -1; }else{ return Math.max(leftHeight,rightHeight)+1; } } public boolean isBalanced1(){ return checkHeight(root) != -1; } /** * @return the root */ public TreeNode getRoot() { return root; }}
测试类代码 :
public class Test { /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here BinaryTree binaryTree=new BinaryTree(); binaryTree.insert(1,2); binaryTree.insert(3,4); binaryTree.insert(7,6); binaryTree.insert(4,8); binaryTree.insert(5,9); System.out.println(binaryTree.getRoot().key); System.out.print("前序遍历(递归):"+"\t"); binaryTree.preOrder(); System.out.print("中序遍历(递归):"+"\t"); binaryTree.midOrder(); System.out.print("后序遍历(递归):"+"\t"); binaryTree.postOrder(); System.out.print("\n前序遍历(非递归):"+"\t"); binaryTree.preOrderTraverse(); System.out.print("中序遍历(非递归):"+"\t"); binaryTree.inOrderTraverse(); System.out.print("后序遍历(非递归):"+"\t"); binaryTree.postOrderTraverse(); System.out.print("\n层次遍历(非递归):"+"\t"); binaryTree.levelOrder(); }}
阅读全文
0 0
- 二叉查找树的各种操作(插入、删除、查找、遍历)
- 二叉树的查找,插入,删除,遍历,最小值,最大值 操作
- 二叉查找树的操作(插入、删除、查找)
- 二叉查找树(插入、查找、遍历、删除.........)
- 二叉树的链式实现(插入,查找,遍历,删除)
- 简易版二叉查找树(查找,插入,遍历,删除)
- 二叉查找树的基本操作(建立,插入,删除,遍历)
- 二叉树2(二叉查找树的插入、查找、删除、遍历)
- 二叉查找树的基本操作之查找插入删除
- 二叉查找树的插入、删除、查找操作
- 二叉查找树的插入,删除,查找
- 二叉查找树的插入,删除,查找
- 二叉查找树的插入,删除,查找
- 二叉树的创建,遍历,查找,删除,插入,修改
- 算法学习----二叉树的查找、 删除、插入、遍历
- 二叉树的遍历、查找、插入以及删除
- 顺序二叉树的建立、查找、删除、插入、替换、遍历
- 关于搜索二叉树的各种操作(插入,删除,输出,查找,递归非递归排序)
- 用java从sql server2008中读取得到的date时间数据比数据库里的实际时间要少两天
- 2677 4-1 复数类的运算符重载
- ubuntu 查看日历,日期
- 清橙A1019. 枚举字串
- 通过环境变量修改java版本不生效
- 二叉查找树的各种操作(插入、删除、查找、遍历)
- 安装织梦系统出现data无写入权限
- ubuntu 关机重启
- LeetCode题解 第十二周
- 进程调度实验(最高优先数优先算法)的java实现
- Mysql动态创建表
- 织梦重新安装出现 dir
- caffe之python接口实战 :detection 官方教程源码解析
- 手写线程池