当前位置: 首页 > news >正文

山西公司网站建设企业网站管理系统最新4湖南岚鸿牛x1 0

山西公司网站建设,企业网站管理系统最新4湖南岚鸿牛x1 0,5188关键词挖掘,企业网站特点分析与描述原文链接#xff1a; 使用 Go 语言实现二叉搜索树 二叉树是一种常见并且非常重要的数据结构#xff0c;在很多项目中都能看到二叉树的身影。 它有很多变种#xff0c;比如红黑树#xff0c;常被用作 std::map 和 std::set 的底层实现#xff1b;B 树和 B 树#xff0c;…原文链接 使用 Go 语言实现二叉搜索树 二叉树是一种常见并且非常重要的数据结构在很多项目中都能看到二叉树的身影。 它有很多变种比如红黑树常被用作 std::map 和 std::set 的底层实现B 树和 B 树广泛应用于数据库系统中。 本文要介绍的二叉搜索树用的也很多比如在开源项目 go-zero 中就被用来做路由管理。 这篇文章也算是一篇前导文章介绍一些必备知识下一篇再来介绍具体在 go-zero 中的应用。 二叉搜索树的特点 最重要的就是它的有序性在二叉搜索树中每个节点的值都大于其左子树中的所有节点的值并且小于其右子树中的所有节点的值。 这意味着通过二叉搜索树可以快速实现对数据的查找和插入。 Go 语言实现 本文主要实现了以下几种方法 Insert(t)插入一个节点Search(t)判断节点是否在树中InOrderTraverse()中序遍历PreOrderTraverse()前序遍历PostOrderTraverse()后序遍历Min()返回最小值Max()返回最大值Remove(t)删除一个节点String()打印一个树形结构 下面分别来介绍首先定义一个节点 type Node struct {key intvalue Itemleft *Node //leftright *Node //right }定义树的结构体其中包含了锁是线程安全的 type ItemBinarySearchTree struct {root *Nodelock sync.RWMutex }插入操作 func (bst *ItemBinarySearchTree) Insert(key int, value Item) {bst.lock.Lock()defer bst.lock.Unlock()n : Node{key, value, nil, nil}if bst.root nil {bst.root n} else {insertNode(bst.root, n)} }// internal function to find the correct place for a node in a tree func insertNode(node, newNode *Node) {if newNode.key node.key {if node.left nil {node.left newNode} else {insertNode(node.left, newNode)}} else {if node.right nil {node.right newNode} else {insertNode(node.right, newNode)}} }在插入时需要判断插入节点和当前节点的大小关系保证搜索树的有序性。 中序遍历 func (bst *ItemBinarySearchTree) InOrderTraverse(f func(Item)) {bst.lock.RLock()defer bst.lock.RUnlock()inOrderTraverse(bst.root, f) }// internal recursive function to traverse in order func inOrderTraverse(n *Node, f func(Item)) {if n ! nil {inOrderTraverse(n.left, f)f(n.value)inOrderTraverse(n.right, f)} }前序遍历 func (bst *ItemBinarySearchTree) PreOrderTraverse(f func(Item)) {bst.lock.Lock()defer bst.lock.Unlock()preOrderTraverse(bst.root, f) }// internal recursive function to traverse pre order func preOrderTraverse(n *Node, f func(Item)) {if n ! nil {f(n.value)preOrderTraverse(n.left, f)preOrderTraverse(n.right, f)} }后序遍历 func (bst *ItemBinarySearchTree) PostOrderTraverse(f func(Item)) {bst.lock.Lock()defer bst.lock.Unlock()postOrderTraverse(bst.root, f) }// internal recursive function to traverse post order func postOrderTraverse(n *Node, f func(Item)) {if n ! nil {postOrderTraverse(n.left, f)postOrderTraverse(n.right, f)f(n.value)} }返回最小值 func (bst *ItemBinarySearchTree) Min() *Item {bst.lock.RLock()defer bst.lock.RUnlock()n : bst.rootif n nil {return nil}for {if n.left nil {return n.value}n n.left} }由于树的有序性想要得到最小值一直向左查找就可以了。 返回最大值 func (bst *ItemBinarySearchTree) Max() *Item {bst.lock.RLock()defer bst.lock.RUnlock()n : bst.rootif n nil {return nil}for {if n.right nil {return n.value}n n.right} }查找节点是否存在 func (bst *ItemBinarySearchTree) Search(key int) bool {bst.lock.RLock()defer bst.lock.RUnlock()return search(bst.root, key) }// internal recursive function to search an item in the tree func search(n *Node, key int) bool {if n nil {return false}if key n.key {return search(n.left, key)}if key n.key {return search(n.right, key)}return true }删除节点 func (bst *ItemBinarySearchTree) Remove(key int) {bst.lock.Lock()defer bst.lock.Unlock()remove(bst.root, key) }// internal recursive function to remove an item func remove(node *Node, key int) *Node {if node nil {return nil}if key node.key {node.left remove(node.left, key)return node}if key node.key {node.right remove(node.right, key)return node}// key node.keyif node.left nil node.right nil {node nilreturn nil}if node.left nil {node node.rightreturn node}if node.right nil {node node.leftreturn node}leftmostrightside : node.rightfor {//find smallest value on the right sideif leftmostrightside ! nil leftmostrightside.left ! nil {leftmostrightside leftmostrightside.left} else {break}}node.key, node.value leftmostrightside.key, leftmostrightside.valuenode.right remove(node.right, node.key)return node }删除操作会复杂一些分三种情况来考虑 如果要删除的节点没有子节点只需要直接将父节点中指向要删除的节点指针置为 nil 即可如果删除的节点只有一个子节点只需要更新父节点中指向要删除节点的指针让它指向删除节点的子节点即可如果删除的节点有两个子节点我们需要找到这个节点右子树中的最小节点把它替换到要删除的节点上。然后再删除这个最小节点因为最小节点肯定没有左子节点所以可以应用第二种情况删除这个最小节点即可 最后是一个打印树形结构的方法在实际项目中其实并没有实际作用 func (bst *ItemBinarySearchTree) String() {bst.lock.Lock()defer bst.lock.Unlock()fmt.Println(------------------------------------------------)stringify(bst.root, 0)fmt.Println(------------------------------------------------) }// internal recursive function to print a tree func stringify(n *Node, level int) {if n ! nil {format : for i : 0; i level; i {format }format ---[ levelstringify(n.left, level)fmt.Printf(format%d\n, n.key)stringify(n.right, level)} }单元测试 下面是一段测试代码 func fillTree(bst *ItemBinarySearchTree) {bst.Insert(8, 8)bst.Insert(4, 4)bst.Insert(10, 10)bst.Insert(2, 2)bst.Insert(6, 6)bst.Insert(1, 1)bst.Insert(3, 3)bst.Insert(5, 5)bst.Insert(7, 7)bst.Insert(9, 9) }func TestInsert(t *testing.T) {fillTree(bst)bst.String()bst.Insert(11, 11)bst.String() }// isSameSlice returns true if the 2 slices are identical func isSameSlice(a, b []string) bool {if a nil b nil {return true}if a nil || b nil {return false}if len(a) ! len(b) {return false}for i : range a {if a[i] ! b[i] {return false}}return true }func TestInOrderTraverse(t *testing.T) {var result []stringbst.InOrderTraverse(func(i Item) {result append(result, fmt.Sprintf(%s, i))})if !isSameSlice(result, []string{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}) {t.Errorf(Traversal order incorrect, got %v, result)} }func TestPreOrderTraverse(t *testing.T) {var result []stringbst.PreOrderTraverse(func(i Item) {result append(result, fmt.Sprintf(%s, i))})if !isSameSlice(result, []string{8, 4, 2, 1, 3, 6, 5, 7, 10, 9, 11}) {t.Errorf(Traversal order incorrect, got %v instead of %v, result, []string{8, 4, 2, 1, 3, 6, 5, 7, 10, 9, 11})} }func TestPostOrderTraverse(t *testing.T) {var result []stringbst.PostOrderTraverse(func(i Item) {result append(result, fmt.Sprintf(%s, i))})if !isSameSlice(result, []string{1, 3, 2, 5, 7, 6, 4, 9, 11, 10, 8}) {t.Errorf(Traversal order incorrect, got %v instead of %v, result, []string{1, 3, 2, 5, 7, 6, 4, 9, 11, 10, 8})} }func TestMin(t *testing.T) {if fmt.Sprintf(%s, *bst.Min()) ! 1 {t.Errorf(min should be 1)} }func TestMax(t *testing.T) {if fmt.Sprintf(%s, *bst.Max()) ! 11 {t.Errorf(max should be 11)} }func TestSearch(t *testing.T) {if !bst.Search(1) || !bst.Search(8) || !bst.Search(11) {t.Errorf(search not working)} }func TestRemove(t *testing.T) {bst.Remove(1)if fmt.Sprintf(%s, *bst.Min()) ! 2 {t.Errorf(min should be 2)} }上文中的全部源码都是经过测试的可以直接运行并且已经上传到了 GitHub需要的同学可以自取。 以上就是本文的全部内容如果觉得还不错的话欢迎点赞转发和关注感谢支持。 源码地址 https://github.com/yongxinz/go-example 推荐阅读 Go 语言 select 都能做什么Go 语言 context 都能做什么 参考文章 https://flaviocopes.com/golang-data-structure-binary-search-tree/
http://www.pierceye.com/news/363886/

相关文章:

  • 国基建设集团有限公司网站学校网站网页模板
  • 舟山网站开发免费com域名网站
  • 网站开发 脚本之家怎么注册一个企业邮箱
  • 青岛做网站公企业管理软件销售
  • 简约风格的网站宁波余姚网站建设
  • 口碑好的免费网站建设企业做网站电话约见客户的对话
  • 做网站采集传统的网站开发模式
  • 网站用哪个软件做中国建设银行行号查询
  • 公司简介网站模板常州建设工程信息网
  • 综合类门户网站有哪些wordpress媒体库一直转圈
  • 官方网站建设属于什么科目室内设计很多人都干不下去了
  • 如何保存个人网站部队网站模板
  • 郑州哪家专业做淘宝网站佛山网站建设no.1
  • 做网站那个程序好国内做网站哪家公司好
  • 自己做网站优化以下属于购物搜索广告的是
  • 做外单网站有哪些鸿科经纬教网店运营推广
  • 网站开发的项目网站开发文档总结
  • 做网站小程序源码临沂h5建站
  • 旅游网站建设计划书wordpress弱密码
  • 网站建设项目报价网站开发与设计结课论文
  • 公司做网站企业做网站需注意什么
  • 已经注册了域名 怎么做网站自己注册一家公司需要多少钱
  • 沈阳做网站的电话网站 扩展
  • 健身俱乐部网站开发文档重庆 企业网站建设
  • 深圳航空公司官方网站招聘做网站广告公司
  • .php的网站是怎么做的最美情侣免费视频
  • v9网站模板学做西点的网站
  • 网站查询空间商工厂生产erp管理系统
  • 365房产南京网站响应式wordpress主题
  • 上海网站建设 app开发佛山黄页企业名录