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 数据结构--二分查找树的更多相关文章

  1. lintcode-106-排序列表转换为二分查找树

    106-排序列表转换为二分查找树 给出一个所有元素以升序排序的单链表,将它转换成一棵高度平衡的二分查找树 样例 标签 递归 链表 思路 类似于二分查找,每次将链表二分,中间节点作为根节点,在建立左子树 ...

  2. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  3. 手把手教你用java实现二分查找树及其相关操作

    二分查找树(Binary Search Tree)的基本操作有搜索.求最大值.求最小值.求前继.求后继.插入及删除. 对二分查找树的进行基本操作所花费的时间与树的高度成比例.例如有n个节点的完全二叉树 ...

  4. 数据结构---平衡查找树之B树和B+树(转)

    本文转载自:http://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html 前面讲解了平衡查找树中的2-3树以及其实现红 ...

  5. SPOJ TEMPLEQ - Temple Queues(二分查找+树状数组)

    题意: 有N个队伍(1 <= N <= 100,000),每个队伍开始有ai个人[0 <= ai<= 100,000,000],有Q个操作[0<=Q<= 500,0 ...

  6. python数据结构之树(二分查找树)

    本篇学习笔记记录二叉查找树的定义以及用python实现数据结构增.删.查的操作. 二叉查找树(Binary Search Tree) 简称BST,又叫二叉排序树(Binary Sort Tree),是 ...

  7. Holedox Eating HDU - 4302 2012多校C 二分查找+树状数组/线段树优化

    题意 一个长度$n<=1e5$的数轴,$m<=1e5$个操作 有两种一些操作 $0$  $x$ 在$x$放一个食物 $1$ 一个虫子去吃最近的食物,如果有两个食物一样近,不转变方向的去吃 ...

  8. 二分查找树按照key值划分

    #include <iostream>#include <vector>#include <algorithm>#include <string>#in ...

  9. js二分查找树实现

    function BinaryTree() { var Node = function(key) { this.key = key; this.left = null; this.right = nu ...

随机推荐

  1. JavaWeb 后端 <十> 之 数据池 C3P0 DPCB JNDI

    一.数据库连接池原理:(理解) //模拟数据库连接池的原理 public class ConnectionPoolDemo { private static List<Connection> ...

  2. SQL Server 2012 案例教程(贾祥素)——学习笔记

    第2章 SQL Server 2012概述 1.SQL(Structed Query Language),结构化查询语言. 2.SSMS(SQL Server Mangement Studio),SQ ...

  3. 配置ssh免密码登录——集群学习日记

    度过了难熬的考试月时期之后,最近和小伙伴一起参加的的比赛进入了紧张的准备时期.在进行工作的时候,发现有很多基础的知识点,自己不是很清楚以及了解,所以在想,要不就边学习的时候边写下学习日记,以供自己后来 ...

  4. Selenium对浏览器支持的版本

    最新的selenium与几种常用浏览器的版本兼容情况: selenium 3.4.0 : Mozilla GeckoDriver 0.18  --  Firefox 53 - 56 Google Ch ...

  5. iOS开发实战-时光记账Demo 网络版

    之前写了一个本地数据库版本 戳这里 现在这个就是增加了后台 登录注册页面以及web的上传记录展示页面 含有少量php有兴趣可以看下 另外demo中包括数据库操作.json.网络请求等都没有用到第三方库 ...

  6. storm从入门到放弃(一),storm介绍

    背景:目前就职于国内最大的IT咨询公司,恰巧又是毕业季,所在部门招了100多个应届毕业生,本人要跟部门新人进行为期一个月的大数据入职培训,特此将整理的文档分享出来. 原文和作者一起讨论:http:// ...

  7. 如何使用lxml的XPath功能

    用python写爬虫呢,最常见的过滤方式有BeautifulSoup, css selector, XPath, 如果使用前两个,BeautifulSoup包就能解决,然而使用XPath,就要引入lx ...

  8. iOS-联系人应用(一)

    环境:xcode6,iphone 4s simulator with iOS8.0 一.功能界面介绍 1.1 应用启动进入联系人列表页面,数据为模拟数据,来源与一个plist文件: 1.2 点击右上角 ...

  9. java_AWT常用组件

    Button:按钮,可接受单击操作. Canvas:用于绘图的画布. Checkbox:复选框组件(也可以变成单选框组件). CheckboxGroup:用于将多个Checkbox组件合成一组,一组C ...

  10. 2.ssh密钥登陆(ssh无密码登陆)

    1.A主机生成密钥对 ssh-keygen  -t  rsa 2.将A主机的公钥发给B主机 scp  id_rsa.pub  linux2:/cloud                         ...