详谈二叉搜索树
Posted 勇敢牛牛不怕困难@帅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详谈二叉搜索树相关的知识,希望对你有一定的参考价值。
详谈二分搜索树
二分搜索树的概念
在了解二分搜索树之前,我们得弄清楚什么是二叉树。
什么是二叉树?
二分搜索树
二分搜索树的创建以及实现其方法
1.内部结构
内部有一个结点类,作为二分搜索树的成员变量使用
private class Node{
public E e;//结点元素
public Node left,right;//左右结点
public Node (E e){//初始化
this.e = e;
left = null;
right = null;
}
public String toString(){
return e.toString();
}
}
2.构造方法与成员变量
初始化成员变量
private Node root;//根节点
private int size;//有效结点个数
public BinarySearchTree(){//构造方法
size =0;
root = null;
}
3.增添元素
根据元素值大小决定去向,小于父亲节点在左边,大于在右边
public int size(){//获取有效长度
return size;
}
public boolean isEmpty(){//判断是否为空
return size==0&&root==null;
}
public void clear(){
size =0;
root = null;
}
public void add(E e){增添元素
root = add(root,e);//在根节点的基础上去添加
}
private Node add(Node node,E e){
if(node==null){
size++;
return new Node(e);
}
if(e.compareTo(node.e)>0){//e大于父节点的值
node.right = add(node.right,e);
}else if(e.compareTo(node.e)<0){
node.left = add(node.left,e);
}else {
node.e = e;
}
return node;
}
4.遍历元素
遍历元素总共有四种种先序、后序、中序和层次遍历。
private void preOrderNR(){//先序非递归遍历
Stack<Node> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
Node node = stack.pop();
System.out.print(node.e+" ");
if (node.right!=null){//利用栈先入右节点,在入左节点 先进后出 后进先出
stack.push(node.right);
} if(node.left!=null){
stack.push(node.left);
}
}
}
private void preOrder(Node node){//先序递归遍历
if(node == null){
return;
}
System.out.print(node.e+" ");
preOrder(node.left);
preOrder(node.right);
}
public void inOrder(){
inOrder(root);
System.out.println("=========");
inOrderNR();
}
public void inOrder(Node node){//中序递归遍历
if(node==null){
return;
}
inOrder(node.left);
System.out.print(node.e+" ");
inOrder(node.right);
}
public void inOrderNR(){//中序非递归遍历
Stack<Node> stack = new Stack();
Node p =root;
while(p!=null){
stack.push(p);
p = p.left;
}
while(!stack.isEmpty()){
Node ret = stack.pop();
System.out.print(ret.e+" ");
if(ret.right!=null){
p = ret.right;
while(p!=null){
stack.push(p);
p = p.left;
}
}
}
}
public void postOrder(){
postOrder(root);
System.out.println();
postOrderNR();
}
private void postOrder(Node node){//后序递归遍历
if(node == null){
return ;
}
postOrder(node.left);
postOrder(node.right);
System.out.print(node.e+" ");
}
private void postOrderNR() {//后序非递归遍历
Stack<Node> stack = new Stack<>();
Node node = root;
Node pre = null;
while(!stack.isEmpty()||node!=null){
while (node!=null){
stack.push(node);
node = node.left;
}
if (!stack.isEmpty()){
node = stack.pop();
if(node.right==null||pre==node.right){
System.out.print(node.e+" ");
pre = node;
node =null;
}else{
stack.push(node);
node = node.right;
}
}
}
}
public void levelOrder(){//层序遍历
Queue<Node> que = new LinkedList<>();
que.add(root);
while(!que.isEmpty()){
Node e = que.poll();
System.out.print(e.e);
if(e.left!=null){
que.add(e.left);
}
if(e.right!=null){
que.add(e.right);
}
}
}
5.判断元素是否存在
目的是为了判断一个元素是否在二分查找树中
public boolean contains(E e){
return contains(root,e);
}
private boolean contains(Node node,E e){
if(node == null){
return false;
}
if(e.compareTo(node.e)==0){
return true;
}
return e.compareTo(node.e)>0 ? contains(node.right,e):contains(node.left,e);
}
6.remove移除一个结点
删除一个结点及元素值
public void remove(E e){
root = remove(root,e);
}
public Node remove(Node node,E e){
if(node==null){
return null;
}
if(e.compareTo(node.e)>0){
node.right = remove(node.right,e);
}else if(e.compareTo(node.e)<0){
node.left = remove(node.left,e);
}else{
if(node.left==null){
Node rightNode = node.right;
node.right = null;
size--;
return rightNode;
}
if(node.right==null){
Node leftNode = node.left;
node.left = null;
size--;
return leftNode;
}
Node successor = minimun(minimun(node.right));
successor.right = removemin(node.right);
successor.left = node.left;
node.left =null;
node.right = null;
size--;
return successor;
}
return null;
}
最终整体代码
package com.数据结构.xiaoniu.类;
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.StringStack;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class BinarySearchTree<E extends Comparable<E>> implements Iterable{
private class Node{
public E e;
public Node left,right;
public Node (E e){
this.e = e;
left = null;
right = null;
}
public String toString(){
return e.toString();
}
}
private Node root;
private int size;
public BinarySearchTree(){
size =0;
root = null;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0&&root==null;
}
public void clear(){
size =0;
root = null;
}
public void add(E e){
root = add(root,e);
}
private Node add(Node node,E e){
if(node==null){
size++;
return new Node(e);
}
if(e.compareTo(node.e)>0){
node.right = add(node.right,e);
}else if(e.compareTo(node.e)<0){
node.left = add(node.left,e);
}else {
node.e = e;
}
return node;
}
public boolean contains(E e){
return contains(root,e);
}
private boolean contains(Node node,E e){
if(node == null){
return false;
}
if(e.compareTo(node.e)==0){
return true;
}
return e.compareTo(node.e)>0 ? contains(node.right,e):contains(node.left,e);
}
public void preOrder(){
preOrder(root);
System.out.println();
preOrderNR();
}
private void preOrderNR(){
Stack<Node> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
Node node = stack.pop();
System.out.print(node.e+" ");
if (node.right!=null){//利用栈先入右节点,在入左节点 先进后出 后进先出
stack.push(node.right);
} if(node.left!=null){
stack.push(node.left);
}
}
}
private void preOrder(Node node){
if(node == null){
return;
}
System.out.print(node.e+" ");
preOrder(node.left);
preOrder(node.right);
}
public void inOrder(){
inOrder(root);
System.out.println("=========");
inOrderNR();
}
public void inOrder(Node node)C++-二叉搜索树的查找&插入&删除-二叉搜索树代码实现-二叉搜索树性能分析及解决方案
代码随想录Day20-Leetcode654.最大二叉树,617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树