Go 数据结构--二分查找树
Go 数据结构--二分查找树
今天开始一个Go实现常见数据结构的系列吧。有时间会更新其他数据结构。
一些概念
二叉树:二叉树是每个节点最多有两个子树的树结构。
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
满二叉树:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树。
平衡二叉树:平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉查找树:它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉搜索树原理
二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构。中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。搜索,插入,删除的复杂度等于树高,O(log(n)).
实现
上述基本是百度百科的概念,现在来直接上实现代码:
/*
时间:2017/8/24
功能:二叉树
*/
package main
import (
"fmt"
"sync"
)
//二叉树节点结构
type Node struct {
data int
left *Node
right *Node
}
//二叉查找树结构
type BST struct {
root *Node
lock sync.RWMutex
}
//插入方法(判断位置 中序遍历)
func insertNode(node *Node, addNode *Node) {
if addNode.data < node.data {
if node.left == nil {
node.left = addNode
} else {
insertNode(node.left, addNode)
}
} else {
if node.right == nil {
node.right = addNode
} else {
insertNode(node.right, addNode)
}
}
}
//插入操作
func (t *BST) Insert(data int) {
t.lock.Lock()
defer t.lock.Unlock()
node := &Node{
data: data,
left: nil,
right: nil,
}
if t.root == nil {
t.root = node
} else {
insertNode(t.root, node)
}
}
//先序遍历
func PreOrderTraverse(bst *Node) {
if bst != nil {
fmt.Printf("%d ", bst.data)
PreOrderTraverse(bst.left)
PreOrderTraverse(bst.right)
}
}
//中序遍历
func InOrderTraverse(bst *Node) {
if bst != nil {
InOrderTraverse(bst.left)
fmt.Printf("%d ", bst.data)
InOrderTraverse(bst.right)
}
}
//后序遍历
func PostOrderTraverse(bst *Node) {
if bst != nil {
PostOrderTraverse(bst.left)
PostOrderTraverse(bst.right)
fmt.Printf("%d ", bst.data)
}
}
//查找
func SearchBST(node *Node, key int) bool {
if node == nil {
return false
}
if key == node.data {
return true
}
if key < node.data {
return SearchBST(node.left, key)
} else {
return SearchBST(node.right, key)
}
}
//删除执行函数
func remove(node *Node, key int) *Node {
if node == nil {
return nil
}
if key == node.data {
if node.left == nil && node.right == nil {
node = nil
return nil
}
if node.left == nil {
node = node.right
return node
}
if node.right == nil {
node = node.left
return node
}
rightside := node.right
for {
if rightside != nil && rightside.left != nil {
rightside = rightside.left
} else {
break
}
}
node.data = rightside.data
node.right = remove(node.right, node.data)
return node
}
if key < node.data {
node.left = remove(node.left, key)
return node
} else {
node.right = remove(node.right, key)
return node
}
}
//删除操作
func (t *BST) Remove(key int) {
t.lock.Lock()
defer t.lock.Unlock()
remove(t.root, key)
}
func main() {
var t BST
t.Insert(2)
t.Insert(6)
t.Insert(5)
t.Insert(1)
t.Insert(10)
t.Insert(8)
fmt.Println("PREORDER...")
PreOrderTraverse(t.root)
fmt.Println("\nINORDER...")
InOrderTraverse(t.root)
fmt.Println("\nPOSTORDER...")
PostOrderTraverse(t.root)
fmt.Printf("\n")
fmt.Println("Search...")
fmt.Println(SearchBST(t.root, 6))
fmt.Println("Remove...")
t.Remove(6)
fmt.Println("PREORDER...")
PreOrderTraverse(t.root)
fmt.Println("\nINORDER...")
InOrderTraverse(t.root)
fmt.Println("\nPOSTORDER...")
PostOrderTraverse(t.root)
fmt.Printf("\n")
fmt.Println("Search...")
fmt.Println(SearchBST(t.root, 6))
}
执行结果
PREORDER...
2 1 6 5 10 8
INORDER...
1 2 5 6 8 10
POSTORDER...
1 5 8 10 6 2
Search...
true
Remove...
PREORDER...
2 1 8 5 10
INORDER...
1 2 5 8 10
POSTORDER...
1 5 10 8 2
Search...
false
总结
照例得总结一波,其实每什么好总结的,大家都熟悉的数据结构。在增删查的复杂度比较均衡。拿来练手非常不错。
Go 数据结构--二分查找树的更多相关文章
- lintcode-106-排序列表转换为二分查找树
106-排序列表转换为二分查找树 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 样例 标签 递归 链表 思路 类似于二分查找,每次将链表二分,中间节点作为根节点,在建立左子树 ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- 手把手教你用java实现二分查找树及其相关操作
二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前继.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树 ...
- 数据结构---平衡查找树之B树和B+树(转)
本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...
- SPOJ TEMPLEQ - Temple Queues(二分查找+树状数组)
题意: 有N个队伍(1 <= N <= 100,000),每个队伍开始有ai个人[0 <= ai<= 100,000,000],有Q个操作[0<=Q<= 500,0 ...
- python数据结构之树(二分查找树)
本篇学习笔记记录二叉查找树的定义以及用python实现数据结构增.删.查的操作. 二叉查找树(Binary Search Tree) 简称BST,又叫二叉排序树(Binary Sort Tree),是 ...
- Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化
题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$ $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...
- 二分查找树按照key值划分
#include <iostream>#include <vector>#include <algorithm>#include <string>#in ...
- js二分查找树实现
function BinaryTree() { var Node = function(key) { this.key = key; this.left = null; this.right = nu ...
随机推荐
- 使用ajax提交form表单(转)
前言 使用ajax请求数据,很多人都会,比如说: $.post(path,{data:data},function(data){ ... },"json"); 又或者是这样的aja ...
- JavaService实现Windows服务
下载JavaService.exe文件 下载地址:http://pan.baidu.com/s/1boWk1uJ(支持Windows 7 64位) 创建server文件目录 在D盘新建一个文件夹如:D ...
- PB程序源码文件结构 pbl文件 pbd文件
最近公司给了一套PB的源码,一个8.0,一个9.0,让给一个客户做软件整合,之前只听过PB看过别人写代码,为了快速上手,了解了一下PB的文件,记录如下:pbl为pb源码文件 pbd为程序编译后的文件 ...
- 使用intelliJ创建 spring boot + gradle + mybatis站点
Spring boot作为快速入门是不错的选择,现在似乎没有看到大家写过spring boot + gradle + mybatis在intellij下的入门文章,碰巧.Net同事问到,我想我也可以写 ...
- 记一次sql server 性能调优,查询从20秒至2秒
一.需求 需求很简单,就是需要查询一个报表,只有1个表,数据量大约60万左右,但是中间有些逻辑. 先说明一下服务器配置情况:1核CPU.2GB内存.机械硬盘.Sqlserver 2008 R2.Win ...
- nyoj_14:会场安排问题
一道很经典的贪心问题 题目链接: http://acm.nyist.net/JudgeOnline/problem.php?pid=14 #include<iostream> #inclu ...
- JavaScript中Function原型及其prototype属性的简单应用
大家都知道在JavaScript中是没有类的概念的,但是却是有对象的概念的.有的人可能理解对象和类有些迷糊,这里简单的概括一下他们之间的区别: 类:抽象的概念,例如人,动物,汽车等都可以抽象成一个类 ...
- html5 01 随记
一 HTML 是一种制作网站的标记语言 二.HTML基本语法 HTML 标签 html标签是html中的最基本单位 也是最重要的部分 通常使用尖角号 开始"<"和结束&qu ...
- ABP从入门到精通(2):aspnet-zero-core 使用MySql数据库
关于 asp.net zero core 项目的启动及说明,请观看我前面的博文 http://www.cnblogs.com/stulzq/p/7237153.html 本操作对于ABP默认项目应该也 ...
- 大数据与Java的关系
随着2017年大数据各种应用的发展,大数据的价值得以充分的发挥,大数据已在企业.社会各个层面都成为重要的手段,数据已成为新的企业战略制高点,也是各个企业争夺的新焦点.那么我们一直在说着的大数据究竟是什 ...