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/
有疑问加站长微信联系(非本文作者)