内容简介:[TOC]单向链表的实现[参考代码]
ARTS 第12周分享
[TOC]
Algorithm
单向链表的实现
[参考代码]
type HeroNode struct { No int Name string NickName string next *HeroNode } type HeroList struct { head *HeroNode } //新建节点 func NewHeroNode(no int, name, nickName string) *HeroNode { return &HeroNode{No: no, Name: name, NickName: nickName} } // 新建链表 func NewHeroList() HeroList { return HeroList{NewHeroNode(0, "", "")} } // 添加 func (h *HeroList) add(heroNode *HeroNode) { tmp := h.head for { if (*tmp).next == nil { break } tmp = tmp.next } tmp.next = heroNode } // 遍历 func (h *HeroList) list() { if h.head.next == nil { fmt.Println("empty list") return } tmp := h.head.next for tmp != nil { fmt.Printf("number:%d,\tname: %s,\tnickName:%s\n", tmp.No, tmp.Name, tmp.NickName) tmp = tmp.next } fmt.Println("list finished...") } // 删除 func (h *HeroList) del(no int) { if h.head.next == nil { fmt.Println("empty list") return } tmp := h.head flag := false for tmp.next != nil { if tmp.next.No == no { flag = true break } tmp = tmp.next } if flag { tmp.next = tmp.next.next } else { fmt.Println("doesn't have this heroNode") } } // 有序添加 func (h *HeroList) orderAdd(newNode *HeroNode) { tmp := h.head for tmp.next != nil { if tmp.next.No > newNode.No { break } else if tmp.next.No == newNode.No { fmt.Println("have the same node") return } tmp = tmp.next } newNode.next = tmp.next tmp.next = newNode } // 更新 func (h *HeroList) update(node *HeroNode) { if h.head.next == nil { fmt.Println("empty link list") return } tmp := h.head.next flag := false for tmp != nil { if tmp.No == node.No { flag = true break } tmp = tmp.next } if flag { tmp.NickName = node.NickName tmp.Name = node.Name } else { fmt.Println("doesn't have this node") } } // 计算长度 func (h *HeroList) count() int { count := 0 tmp := h.head for tmp.next != nil { count++ tmp = tmp.next } return count } // 查找倒数第n个节点 func (h *HeroList) reIndex(no int) *HeroNode { if h.head.next == nil { fmt.Println("empty list") return NewHeroNode(0, "", "") } if no > h.count() || no <= 0 { fmt.Println("invalid index!") return NewHeroNode(0, "", "") } tmp := h.head.next // 倒数第x个节点等于: 正数:len(list) - x for i := 0; i < h.count()-no; i++ { tmp = tmp.next } return tmp } // 逆序 func (h *HeroList) reverse() { // 直接将相邻的元素的指向调转 if h.head.next == nil || h.head.next.next == nil { return } pPre := h.head.next pCur := pPre.next tmp := pCur for pCur != nil { tmp = pCur.next pCur.next = pPre pPre = pCur pCur = tmp } h.head.next.next = nil h.head.next = pPre } // 逆序 func (h *HeroList) reverse2() { // 通过新建一个list // 然后遍历这个old list,将每一元素插入到新list的头节点后面 if h.head.next == nil || h.head.next.next == nil { return } newList := NewHeroList() tmp := h.head.next tmpNext := tmp.next for tmp != nil { tmpNext = tmp.next tmp.next = newList.head.next newList.head.next = tmp tmp = tmpNext } h.head = newList.head } // 逆序遍历 func (h *HeroList) reList() { h.reverse() h.list() h.reverse() } // 逆序遍历 func (h *HeroList) reList2() { // 正序遍历,将每一个结果压入栈中 // 然后将栈的结果输出 if h.head.next == nil { fmt.Println("empty list") return } tmp := h.head.next hStack := NewHeroStack() count := 0 for tmp != nil { hStack.Push(tmp) count++ tmp = tmp.next } for i := 0; i < count; i++ { tmp = hStack.Pop() fmt.Printf("number:%d,\tname:%s,\tnickName:%s\n", tmp.No, tmp.Name, tmp.NickName) } } // 栈实现 type HeroStack struct { heroSlice []*HeroNode lock sync.RWMutex } // 栈构造方法 func NewHeroStack() HeroStack { return HeroStack{heroSlice: []*HeroNode{}} } // 压入栈 func (h *HeroStack) Push(hero *HeroNode) { h.lock.Lock() h.heroSlice = append(h.heroSlice, hero) h.lock.Unlock() } // 从栈中提取元素 func (h *HeroStack) Pop() *HeroNode { h.lock.Lock() hero := h.heroSlice[len(h.heroSlice)-1] h.heroSlice = h.heroSlice[:len(h.heroSlice)-1] h.lock.Unlock() return hero } // 合并两个有序单项链表 func mergeOrderList(list1, list2 *HeroList) HeroList { // 遍历两个列表 // 比较遍历到的单前元素的大小,依次加入一个新的列表 tmp1 := list1.head.next tmp2 := list2.head.next lens := list1.count() + list2.count() newList := NewHeroList() for i := 0; i < lens; i++ { if tmp1 == nil { tmpNext := tmp2.next newList.orderAdd(tmp2) tmp2 = tmpNext continue } if tmp2 == nil { tmpNext := tmp1.next newList.orderAdd(tmp1) tmp1 = tmpNext continue } if tmp1.No < tmp2.No { tmpNext := tmp1.next newList.orderAdd(tmp1) tmp1 = tmpNext } else if tmp1.No == tmp2.No { tmpNext := tmp1.next newList.orderAdd(tmp1) tmp1 = tmpNext } else { tmpNext := tmp2.next newList.orderAdd(tmp2) tmp2 = tmpNext } } return newList }
Review
-
Grab a Slice on the Go: https://blog.gojekengineering.com/grab-a-slice-on-the-go-c606344186c1
- 数组在 Go 中是一个值类型,所以当你将一个数组拷贝给一个新的变量时一定是深拷贝
- 不同长度的数组是不同的数据类型,因为长度是数组类型的一部分
- 切片是数组的一种包装形式
- 切片不存储任何数据,它只是底层数组的一个引用
- 创建一个切片的实际过程是:先创建一个数组,然后返回的这个数组的引用
- 切片的长度:当前切片拥有的元素个数
- 切片的容量:当前切片底层数组拥有元素的个数
Tips
最近因为自己git仓库出上传了一些不必要的东西,需要在远端清理,所以仔细了解了一下对于远端的操作
- 删除远程分支:git push origin --delete <branchName>
- 删除远程tag:git push origin --delete tag <tagName>
- 与远程仓库绑定:git remote add origin <git rep URL>
-
重命名远程分支:就是先删除远程分支,再重命名本地分支,再推送到远端
- 删除远程:同上
- 重命名本地分支:git branch origin -m <oldName> <newName>
- 推送分支到远端:git push origin <branchName>
- 本地tag推送到远程:git push --tags
- 获取远程指定tag:git fetch origin tag <tagName>
share
golang 中的内嵌(embeded) https://studygolang.com/articles/6934
-
外部类型只包含了内部类型的类型名, 而没有field 名, 则是内嵌。
- 内嵌的方式: 主要是通过结构体和接口的组合
-
部类型包含了内部类型的类型名,还有filed名,则是聚合。
- (总结:内嵌就是内部类型没有名字,聚合就是内部类型有名字)
-
Interface 不能嵌入非interface的类型。
- 结构体(struct)中内嵌 结构体(struct)
-
在结构体(struct)中内嵌 接口(interface)
- 嵌入interface可以使得一个struct具有内嵌interface的接口,而不需要实现interface中的有声明的函数。
- 只能调用已经实现的函数。
- 声明只要实现了该interface的变量都可以赋值给该interface,从而内嵌与外层结构体,注意:必须是该变量的指针,因为interface是指针类型的变量。
第三周:1, 2, 3, 4, 6, 7 每个职场人,都该知道关于工作的这9个误解: https://mp.weixin.qq.com/s/0D8CMw2PiWRRjdMsetJQhw golang 中的内嵌 (embeded) : https://studygolang.com/articles/6934 空调 能效常识: https://mp.weixin.qq.com/s/T49Qb36y0NRWZAk1F8Yw4w 能效比越大,节省的电能就越多 空调能效比分为:制冷能效比和制热能效比 请停止学习框架: https://mp.weixin.qq.com/s/gQI7cO_vlAEwE3S4P39FeA 理解 struct 内嵌 inteface: https://blog.csdn.net/uudou/article/details/52556840 用故事来给你讲负载均衡的原理: https://mp.weixin.qq.com/s/icEZZw9cp3rrNfxxi9RgRQ 怎样做到不衰老?https://mp.weixin.qq.com/s/NyyTgqjZR-mdDy3-rOJPcg 人生最辉煌的时刻一过,就开始衰老 防止衰老的最好方式就是,让自己一直处于上升期 做一件巨大的工程,要用一辈子去做的工程,人生的辉煌时刻就可以在最后 做价值持续积累的事,比如做一个操作系统,越完善,使用的人就越多,你的影响力就越多 怎么样的go程序设计风格好-owlcache分析有感: https://mp.weixin.qq.com/s/ynDTMF2QXcZGYVvwjZrWLQ 数据结构与算法——单链表: https://mp.weixin.qq.com/s/3oy5fIFciDYnM7RlLLrAMw Golang 在 Mac、 Linux 、Windows 下如何交叉编译: https://blog.csdn.net/panshiqu/article/details/53788067 什么是交叉编译:一个在某个系统平台下可以产生另一个系统平台的可执行文件 详解git fetch与git pull的区别: https://blog.csdn.net/riddle1981/article/details/74938111 git pull 和 git fetch的区别?https://www.zhihu.com/question/38305012 Git查看、删除、重命名远程分支和tag:https://blog.zengrong.net/post/1746.html Grab a Slice on the Go: https://blog.gojekengineering.com/grab-a-slice-on-the-go-c606344186c1 Golang 数据结构:栈与队列: https://wuyin.io/2018/01/30/golang-data-structure-stack-queue/
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
UNIX环境高级编程(第3版)
史蒂文斯 (W.Richard Stevens)、拉戈 (Stephen A.Rago) / 戚正伟、张亚英、尤晋元 / 人民邮电出版社 / 2014-6-1 / 128.00元
《UNIX环境高级编程(第3版)》是被誉为UNIX编程“圣经”的Advanced Programming in the UNIX Environment一书的第3版。在本书第2版出版后的8年中,UNIX行业发生了巨大的变化,特别是影响UNIX编程接口的有关标准变化很大。本书在保持前一版风格的基础上,根据最新的标准对内容进行了修订和增补,反映了最新的技术发展。书中除了介绍UNIX文件和目录、标准I/......一起来看看 《UNIX环境高级编程(第3版)》 这本书的介绍吧!