查找二叉树(插入、删除、查找)实现

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树

如图:

基于这样的特性,查找的时候就很好操作了,从根节点开始,查找,如果值大于节点值,往右找;如果值小于节点值,往左找;如果值刚好相等,就找到了。是不是看着就能写出代码了?这种查找过程很像二分查找法,但是那个是数组结构,这个是树结构。

二叉查找树的操作基本概括为:插入值,删除值,查找值以及二叉树的遍历。

注意的是:这里面,删除是最麻烦的。

(本来觉得写数据结构还是用c语言最好的,直接可以操作指针,清晰明了效率高,但是c确实丢了太久了,而且现在主要目的是温习数据结构和算法的知识,所以只能放弃用c的想法,以后如果需要再学习,先用最熟悉的java来实现代码)

下面来看具体的操作和逻辑,附带贴上代码。

public class SearchTree {
	private TreeNode root;

	public SearchTree() {
	}

	// 中序遍历(递归)
	public void midOrder(TreeNode node) {
		if (node == null) {
			return;
		}
		// 对该节点继续进行左右子节点的遍历
		// 先输出根节点,因为这是前序遍历,根左右
		midOrder(node.lchild);
		System.out.println("二叉树节点 : " + node.data);
		midOrder(node.rchild);
	}

	public TreeNode putTreeNode(int key) {
		TreeNode node = null;
		TreeNode parent = null;
		if (root == null) {
			node = new TreeNode(0, key);
			root = node;
		}
		// 如果根节点已经存在,就要开始判断了
		node = root;
		while (node != null) {
			parent = node;
			if (key > node.data) {
				// 获取右节点
				node = node.rchild;
			} else if (key < node.data) {
				// 获取左节点
				node = node.lchild;
			} else {
				// 相等的话,就啥也不做
				return node;
			}
		}
		// 如果跳出了循环,代表这个节点不存在,需要创建
		node = new TreeNode(0, key);
		// 找到此时node的父节点
		if (key > parent.data) {
			parent.rchild = node;
		} else if (key < parent.data) {
			parent.lchild = node;
		}
		node.parent = parent;
		return node;
	}

	// 删除节点
	public void deleteNode(int key) {
		TreeNode node = searchNode(key);
		if (node == null) {
			throw new RuntimeException("查找该节点不存在!!");
		}
		delete(node);
	}

	public void delete(TreeNode node) {
		if (node == null) {
			throw new RuntimeException("删除该节点不存在!!");
		}
		TreeNode parent = node.parent;
		// 要删除的节点无后代,直接删除
		if (node.lchild == null && node.rchild == null) {
			if (parent.lchild == node) {
				parent.lchild = null;
			} else if (parent.rchild == node) {
				parent.rchild = null;
			}
			return;
		}
		// 被删除节点有左无右
		if (node.lchild != null && node.rchild == null) {
			if (parent.lchild == node) {
				parent.lchild = node.lchild;
			} else if (parent.rchild == node) {
				parent.rchild = node.lchild;
			}
			return;
		}
		// 被删除节点有右无左
		if (node.lchild == null && node.rchild != null) {
			if (parent.rchild == node) {
				parent.rchild = node.rchild;
			} else if (parent.lchild == node) {
				parent.lchild = node.rchild;
			}
			return;
		}
		// 被删除节点左右孩子都有
		// 获取该节点的后继节点
		TreeNode next = getNextNode(node);// 45
		delete(next);
		node.data = next.data;
	}

	/**
	 * @param node
	 *            查找后继节点
	 * @return
	 */
	public TreeNode getNextNode(TreeNode node) {
		if (node == null) {
			return null;
		}
		if (node.rchild != null) {
			// 找某节点最小关键字节点(左树找最大)
			return getMinTreeNode(node.rchild);
		}
		return null;
	}

	private TreeNode getMinTreeNode(TreeNode node) {
		// 一直找左孩子
		if (node == null) {
			return null;
		}
		TreeNode parent = null;
		while (node != null) {
			parent = node;
			node = node.lchild;
		}
		return parent;
	}

	// 查找节点
	public TreeNode searchNode(int key) {
		if (root == null) {
			return null;
		}
		TreeNode node = root;
		while (node != null) {
			if (key > node.data) {
				node = node.rchild;
			} else if (key < node.data) {
				node = node.lchild;
			} else {
				return node;
			}
		}
		// 跳出了上面循环的话,就代表没有该节点。。。
		return null;
	}

	public class TreeNode {
		private int index;
		private int data;
		private TreeNode lchild;
		private TreeNode rchild;
		private TreeNode parent;

		public TreeNode(int index, int data) {
			this.index = index;
			this.data = data;
		}

	}

	public static void main(String[] args) {
		SearchTree searchTree = new SearchTree();
		int[] array = { 50, 30, 15, 45, 60, 55, 70, 58 };
		for (int data : array) {
			searchTree.putTreeNode(data);
		}
		searchTree.midOrder(searchTree.root);
		System.out.println("============");
		searchTree.deleteNode(60);
		searchTree.midOrder(searchTree.root);
	}
}

  

原文地址:https://www.cnblogs.com/Booker808-java/p/8910060.html

时间: 2024-08-26 08:11:45

查找二叉树(插入、删除、查找)实现的相关文章

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

[PHP] 数据结构-链表创建-插入-删除-查找的PHP实现

链表获取元素1.声明结点p指向链表第一个结点,j初始化1开始2.j<i,p指向下一结点,因为此时p是指向的p的next,因此不需要等于3.如果到末尾了,p还为null,就是没有查找到 插入元素1.插入元素和查找类似,找到位置后2.生成新的结点s, s->next=p->next p->next=s; 删除元素1.删除元素,找到位置后2.绕过一下,q=p->next p->next=q->next; <?php class Node{ public $data

ios 字符串的插入删除查找与替换,删除空格

NSString *str1 = @"This is a example.";  NSMutableString *mstr = [[NSMutableString alloc] init]; //创建可变字符串  NSRange substr; //子字符串的范围mstr = [NSMutableString stringWithString:str1];  //插入字符  [mstr insertString:@"very easy " atIndex:10];

链表 创建 插入 删除 查找 合并

最近学习了一下单链表的操作,将代码保存如下,供以后查看. 链表创建: 1.先建立一个不含数据的头指针*head,头指针的链接域为NULL. 2.声明一个用于暂存新申请空间的指针*pc,一个用于保存创建的链表的指针*r,令*r指向*head. 3.在循环中,为指针*pc申请空间,并给数据域赋值,head->next = pc, pc->next = NULL, head = pc. #define _CRT_SECURE_NO_DEPRECATE /*取消scanf,printf不安全之类的错误

链表的创建 查找 排序 插入 删除 逆序 长度 显示

#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <stdbool.h> typedef int elementType; typedef struct node {     int data;     struct node1*next; } LinkList; FILE *fp; LinkList*Creat(int length) {     LinkList*hea

2. C#数据结构与算法 -- 查找算法(顺序查找,哈希查找,二分查找(折半),索引,二叉)

1. 顺序查找算法 ===================================================== 算法思想简单描述: 最突出的查找类型就是从记录集的开始处顺次遍历每条记录,直到找到所要的记录或者是 到达数据集的末尾.这就是所谓的顺序查找.顺序查找(也被称为线性查找)是非常容易实现 的.从数组的起始处开始,把每个访问到的数组元素依次和所要查找的数值进行比较.如果找 到匹配的数据项,就结束查找操作.如果遍历到数组的末尾仍没有产生匹配,那么就说明此数 值不在数组内. ==

数据结构开发(23):二叉树中结点的查找、插入、删除与清除操作

0.目录 1.二叉树中结点的查找操作 2.二叉树中结点的插入操作 3.二叉树中结点的删除操作 4.二叉树中结点的清除操作 5.小结 1.二叉树中结点的查找操作 查找的方式: 基于数据元素值的查找 BTreeNode<T>* find(const T& value) const 基于结点的查找 BTreeNode<T>* find(TreeNode<T>* node) const 树中数据元素和结点的查找: 基于数据元素值的查找: 定义功能:find(node,

重温数据结构:二叉排序树的查找、插入、删除

读完本文你将了解到: 什么是二叉排序树 Binary Sort Tree BST 二叉排序树的关键操作 查找 插入 删除 运行代码测试 一道面试题 总结 Thanks 我们知道,二分查找可以缩短查找的时间,但是有个要求就是 查找的数据必须是有序的.每次查找.操作时都要维护一个有序的数据集,于是有了二叉排序树这个概念. 上篇文章 我们介绍了 二叉树 的概念,二叉树有左右子树之分,想必在区分左右子树时有一定的规则. 现在我们来介绍二叉树的一种特殊形式 - 二叉排序树,了解它的区分策略及常用操作. 什