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

湖北手机网站建设/有什么推广软件

湖北手机网站建设,有什么推广软件,网站做开票,深圳市建设安监站网站前言这里不介绍链表是什么之类的概念,大家可以找一找相关的书籍或文章看看,本文主要是用GO来实现一些链表的操作说明:刚开始学习GO,可能用到的实现方法不是最简便的,意思表达出来了就可以,大家凑合着看【手…

4d99935e0264fba821f8fbe57142ea3c.png

前言

这里不介绍链表是什么之类的概念,大家可以找一找相关的书籍或文章看看,本文主要是用GO来实现一些链表的操作

说明:刚开始学习GO,可能用到的实现方法不是最简便的,意思表达出来了就可以,大家凑合着看【手动狗头】。如有错误,欢迎指正

以下的代码均可从这里获取

https://github.com/Rain-Life/learnGo

收获:做链表的题,一定!一定!一定!要画图!要画图!要画图!不然,特别容易乱,很难一遍写出0 error,0 warning的链表代码

链表

4ad8f04ffd0d53034cdba9b9f9cbc484.png

单链表的基本操作

链表通过指针将一组零散的内存块串联在一起,这里的内存块称为链表的结点。为了将这些节点给串起来,每个链表的结点除了存储数据之外,还会记录下一个结点的指针(即下一个结点的地址),这个指针称为:后继指针

c745187bea50382ec5a47146cf40255d.png

定义单链表基本结构

定义链表结构

//定义结点中数据的类型为接口类型,可收任意类型数据
type Object interface {}//定义结点的结构体
type Node struct {Data ObjectNext *Node
}//定义链表的结构体
type List struct {headNode *Node
}

判断链表是否为空

func (list *List) IsEmpty() bool  {if list.headNode == nil {return true}return false
}

获取链表的长度

func (list *List) Length() int {currentNode := list.headNodecount := 0for currentNode != nil {count++currentNode = currentNode.Next}return count
}

添加结点

向链表头部添加结点

func (list *List) AddFromHead(data Object) *Node {node := &Node{Data:data}if list.IsEmpty() {list.headNode = nodereturn node}node.Next = list.headNodelist.headNode = nodereturn node
}

向链表尾部添加结点

func (list *List) Append(data Object) {node := &Node{Data: data}if list.IsEmpty() {list.headNode = node} else {currentNode := list.headNodefor currentNode.Next != nil {currentNode = currentNode.Next}currentNode.Next = node}
}

向链表中指定位置添加结点

func (list *List) Insert(position int, data Object) {if position <= 1 {list.AddFromHead(data)} else if position > list.Length() {list.Append(data)} else {pre := list.headNodecount := 1for count < (position-1) {pre = pre.Nextcount++}//循环退出以后pre刚好在position-1的位置node := &Node{Data: data}node.Next = pre.Nextpre.Next = node}
}

删除结点

删除链表头部结点

func (list *List) RemoveHeadNde() Object {if list.IsEmpty() {fmt.Println("链表为空")return nil}currentNode := list.headNodeif list.headNode.Next == nil {list.headNode = nilreturn currentNode.Data}list.headNode = currentNode.Nextreturn currentNode.Data
}

删除链表尾部结点

func (list *List) RemoveLastNode() Object {if list.IsEmpty() {return "链表为空"}currentNode := list.headNodefor currentNode.Next.Next != nil {currentNode = currentNode.Next}data := currentNode.Next.DatacurrentNode.Next = nilreturn data
}

删除指定值的结点

func (list *List) Remove(data Object)  {pre := list.headNodeif pre.Data == data{list.headNode = pre.Next} else {for pre.Next != nil {if pre.Next.Data == data {pre.Next = pre.Next.Next} else {pre = pre.Next}}}
}

删除指定位置的结点

func (list *List) RemovePosition(position int)  {pre := list.headNodeif position <= 1 {list.headNode = nil} else if position > list.Length() {fmt.Println("超出链表长度")} else {count :=1for count != position-1 && pre.Next != nil {count++pre = pre.Next}pre.Next = pre.Next.Next}
}

查找结点

链表中是否包含某个值的节点

func (list *List) Contain(data Object) bool {currentNode := list.headNodefor currentNode != nil {if currentNode.Data == data {return true}currentNode = currentNode.Next}return false
}

遍历链表

遍历

func (list *List) Traverse()  {if list.IsEmpty() {fmt.Println("链表为空")}currentNode := list.headNodefor currentNode != nil {fmt.Printf("%vt", currentNode.Data)currentNode = currentNode.Next}
}

测试

package mainimport ("fmt""learnGo/linkedList/node"
)func print(list node.List)  {fmt.Printf("链表长度%dn", list.Length())fmt.Println("遍历链表所有结点:")list.Traverse()fmt.Println()fmt.Println()
}func main() {list := node.List{}//向链表的尾部追加元素fmt.Println("++++++++1、向链表尾部追加结点++++++++")list.Append(3)list.Append(8)list.Append(1)list.Append(9)list.Append("PHP")list.Append("Golang")list.Append("Java")list.Append("JavaScript")print(list)fmt.Println("++++++++2、判断链表是否为空++++++++")fmt.Printf("链表是否为空:%v", list.IsEmpty())fmt.Println()fmt.Println()//向链表的头部添加元素fmt.Println("++++++++3、向链表的头部添加一个结点++++++++")fmt.Println()list.AddFromHead("firstNode")print(list)fmt.Println("++++++++4、向链表尾部添加结点++++++++")fmt.Println()list.Append("lastNode")print(list)fmt.Println("++++++++5、向链表尾部添加结点++++++++")fmt.Println()list.Insert(3, "thirdNode")print(list)fmt.Println("++++++++6、删除链表头结点++++++++")fmt.Println()list.RemoveHeadNde()print(list)fmt.Println("++++++++7、删除链表尾结点++++++++")fmt.Println()list.RemoveLastNode()print(list)fmt.Println("++++++++8、删除链表中指定值的结点++++++++")fmt.Println()list.Remove(9)print(list)fmt.Println("++++++++9、删除链表中指定位置的结点++++++++")fmt.Println()list.RemovePosition(3)print(list)fmt.Println("++++++++10、查询链表中是否包含某一个结点++++++++")fmt.Println()res := list.Contain("Golang")fmt.Printf("是否存在Golang结点:%vn", res)print(list)
}

实现各种类型的链表

各种链表简介

循环链表

循环链表是一种特殊的单链表。循环跟单链表唯一的区别就在尾结点。单链表的尾结点指针指向空地址,表示这就是最后的结点了。而循环链表的尾结点指针是指向链表的头结点

b74d200c8f6234206fe200cc946f9d5e.png

循环链表的优点就是,从链尾到链头比较方便。当要处理的数据具有环型结构特点时,就特别适合采用循环链表

双向链表

和单向链表相比,双向链表有两个指针,指向前一个结点的指针是前驱指针(prev),指向后一个结点的是后继指针(next)

68d5668f579a3250a90dca2e3373562a.png

有了前驱指针,可以更加方便的获取当前结点的前一个结点。按照单链表的方式,我们如果要获取前驱结点,要么遍历的时候用一个变量来保存前驱结点,要么再次遍历获取前驱结点。而双向链表可以在O(1)复杂度下找到前驱结点

单向链表和双向链表对比

  • 如果存储同样多的数据,双向链表要比单链表占用更多的内存空间。虽然两个指针比较浪费存储空间,但可以支持双向遍历,这样也带来了双向链表操作的灵活性
  • 双向链表的插入和删除操作更高效,因为可以很容易获取到前驱结点
  • 如果有一个有序的链表,双向链表的按值查询的效率也要比单链表高一些。因为,我们可以记录上次查找的位置 p,每次查询时,根据要查找的值与 p 的大小关系,决定是往前还是往后查找,所以平均只需要查找一半的数据

双向链表尽管比较费内存,但还是比单链表的应用更加广泛的原因是空间换时间的思想

当内存空间充足的时候,如果我们更加追求代码的执行速度,我们就可以选择空间复杂度相对较高、但时间复杂度相对很低的算法或者数据结构。相反,如果内存比较紧缺,比如代码跑在手机或者单片机上,这个时候,就要反过来用时间换空间的设计思路
来源:数据结构与算法之美

双向循环链表

将循环链表和双向链表结合,得到的就是:双向循环链表

e06ea32f9422f0b269c4758b53200f76.png

各种类型的链表操作

这部分直接上代码了

循环链表

这里直接放完整的各种操作的代码,重点地方会加上说明

loopLinkedList.go

package loopLinkListimport "fmt"//循环链表
type Object interface {}type Node struct {Data ObjectNext *Node
}type List struct {headNode *Node
}//判断循环链表是否为空(与单链表的实现没有区别)
func (list *List) IsEmpty() bool {if list.headNode == nil {return true}return false
}//获取循环链表的长度(与单链表的获取长度区别在于循环的终止条件)
func (list *List) Length() int {if list.headNode == nil {return 0}currentNode := list.headNodecount := 1for currentNode.Next != list.headNode {count++currentNode = currentNode.Next}return count
}//向循环链头部添加结点
func (list *List) AddFromHead(data Object) {node := &Node{Data: data}//链表为空的情况if list.IsEmpty() {list.headNode = nodelist.headNode.Next = list.headNode //单链表没有这一步} else {currentNode := list.headNodefor currentNode.Next != list.headNode { //需要先找到最后一个结点currentNode = currentNode.Next}node.Next = list.headNodecurrentNode.Next = node //单链表没有这一步操作,将最后一个节点的next指向头结点list.headNode = node}
}//向循环链表的尾部添加结点
func (list *List) Append(data Object) {node := &Node{Data: data}if list.IsEmpty() {list.headNode = nodelist.headNode.Next = node} else {currentNode := list.headNodefor currentNode.Next != list.headNode {currentNode = currentNode.Next}currentNode.Next = nodenode.Next = list.headNode //单链表没有这一步操作(让最后一个节点指向头结点)}
}//向循环链表的指定位置添加结点(跟单链表是一样的)
func (list *List) Insert(position int, data Object) {if position <= 1 {list.AddFromHead(data)} else if position > list.Length() {list.Append(data)} else {currentNode := list.headNodecount := 1for count < position-1 {currentNode = currentNode.Nextcount++}node := &Node{Data: data}node.Next = currentNode.NextcurrentNode.Next = node}
}//删除循环链表的头结点
func (list *List) RemoveHeadNde() {if list.IsEmpty() {fmt.Println("链表是空的")return}currentNode := list.headNodelastNode := list.headNode//考虑循环链表只有一个结点的情况if currentNode.Next == list.headNode {list.headNode = nilreturn}for lastNode.Next != list.headNode {lastNode = lastNode.Next}list.headNode = currentNode.NextlastNode.Next = list.headNode
}//删除循环链表的尾结点
func (list *List) RemoveLastNode() {if list.IsEmpty() {fmt.Println("链表是空的")return}currentNode := list.headNode//考虑循环链表只有一个结点的情况if currentNode.Next == list.headNode {list.headNode = nilreturn}for currentNode.Next.Next != list.headNode {currentNode = currentNode.Next}currentNode.Next = list.headNode
}//删除循环链表中指定位置的节点 (需考虑删除的结点是不是第一个或最后一个)
func (list *List) RemovePosition(position int) {if list.IsEmpty() {fmt.Println("链表为空")return}if position <= 1 {list.RemoveHeadNde()} else if position > list.Length() {list.RemoveLastNode()} else {currentNode := list.headNodecount := 1if count != position-1 && currentNode.Next != list.headNode{count++currentNode = currentNode.Next}currentNode.Next = currentNode.Next.Next}
}//删除循环链表中指定值的结点
func (list *List) Remove(data Object) {if list.IsEmpty() {fmt.Println("链表为空")return}currentNode := list.headNode//删除的结点为头结点时if currentNode.Data == data {list.RemoveHeadNde()return}for currentNode.Next != list.headNode {if currentNode.Next.Data == data {currentNode.Next = currentNode.Next.Nextreturn} else {currentNode = currentNode.Next}}if currentNode.Next == list.headNode {list.RemoveLastNode()}
}//查找循环链表中指定结点
func (list *List) Contain(data Object) bool {if list.IsEmpty() {return false}currentNode := list.headNodefor currentNode.Next != list.headNode {if currentNode.Data == data {return true}currentNode = currentNode.Next}if currentNode.Data == data {return true}return false
}//遍历循环链表
func (list *List) Traverse() {if list.IsEmpty() {fmt.Println("循环链表为空")return}currentNode := list.headNodeif currentNode.Next == list.headNode { //兼容循环链表只有一个结点的情况fmt.Printf("%vt", currentNode.Data)return}for currentNode.Next != list.headNode {fmt.Printf("%vt", currentNode.Data)currentNode = currentNode.Next}fmt.Printf("%vt", currentNode.Data)
}

entry.go(测试)

package mainimport ("fmt""learnGo/linkedList/loopLinkList"
)func print(list loopLinkList.List)  {fmt.Printf("链表长度:%dn", list.Length())fmt.Println("遍历链表所有结点:")list.Traverse()fmt.Println()fmt.Println()
}func main() {list := loopLinkList.List{}fmt.Println("++++++++1、判断链表是否为空++++++++")fmt.Printf("链表是否为空:%vn", list.IsEmpty())print(list)fmt.Println("++++++++2、获取链表长度++++++++")fmt.Printf("获取链表长度:%dn", list.Length())print(list)fmt.Println("++++++++3、向循环链头部添加结点++++++++")list.AddFromHead("firstNode")print(list)fmt.Println("++++++++4、向循环链尾部添加结点++++++++")list.Append("lastNode")print(list)fmt.Println("++++++++5、向循环链指定位置添加结点++++++++")list.Insert(1,"secondNode")print(list)fmt.Println("++++++++6、删除循环链的头结点++++++++")list.RemoveHeadNde()print(list)fmt.Println("++++++++7、删除循环链的尾结点++++++++")list.RemoveLastNode()print(list)fmt.Println("++++++++8、查找循环链表中指定结点++++++++")fmt.Printf("是否包含secondNode节点:%vn", list.Contain("secondNode"))print(list)fmt.Println("++++++++9、删除循环链表中指定位置的结点++++++++")list.RemovePosition(1)print(list)fmt.Println("++++++++10、删除循环链表中指定值的结点++++++++")list.Remove("lastNode")print(list)}

双向链表

doublyLinkedList.go

package doublyLinkedListimport ("fmt"
)//双向链表
type Object interface {}type Node struct {Data ObjectPrev,Next *Node
}type List struct {headNode *Node
}//说明
/**
1、如果结点的Next指向为null,则说明是最后一个结点
2、第一个结点的prev指向为空
3、双向链表和单向链表差不多,区别就是删除和添加结点的时候更方便了,因为很方便的可以获取到前一个结点
*///判断双向链表是否为空
func (list *List) IsEmpty() bool {if list.headNode == nil {return true}return false
}//遍历双向链表(跟遍历单链表一模一样)
func (list *List) Traverse() {if list.IsEmpty() {fmt.Println("双线链表为空")return}currentNode := list.headNodefor currentNode != nil {fmt.Printf("%vt", currentNode.Data)currentNode = currentNode.Next}
}//获取双向链表的长度(跟获取单链表长度一模一样)
func (list *List) Length() int {if list.IsEmpty() {return 0}count := 0currentNode := list.headNodefor currentNode != nil {count++currentNode = currentNode.Next}return count
}//从双向链表头部开始增加结点
func (list *List) AddFromHead(data Object) *Node {node := &Node{Data: data}if list.IsEmpty() {list.headNode = nodereturn node}list.headNode.Prev = nodenode.Next = list.headNodelist.headNode = nodereturn node
}//从双向链表尾部添加结点
func (list *List) Append(data Object) {node := &Node{Data: data}if list.IsEmpty() {list.headNode = node} else {currentNode := list.headNodefor currentNode.Next != nil {currentNode = currentNode.Next}currentNode.Next = nodenode.Prev = currentNode}
}/*** 向双向链表的指定位置插入结点** 说明:在单向链表中,我是通过找到我要插入的这个结点的前一个结点,然后将要插入的结点,* 插入到这个结点的后边(因为插入结点需要找到当前结点的前一个结点,为了避免再次遍历找前一个结点,所以采用了这种方式)* 而双向链表就不需要这么做了,找到指定位置的结点,新的插入到它前边就可以了*/
func (list *List) Insert(position int, data Object) {if position <= 1 {list.AddFromHead(data)} else if position > list.Length() {list.Append(data)} else {currentNode := list.headNodecount := 1for count != position {currentNode = currentNode.Nextcount++}//找到了指定位置的结点,然后将要插入的结点,插到这个节点前边即可(注意顺序,画图最容易理解)node := &Node{Data: data}node.Next = currentNodenode.Prev = currentNode.PrevcurrentNode.Prev.Next = nodecurrentNode.Prev = node}
}//删除链表头结点
func (list *List) RemoveHeadNde() Object {if list.IsEmpty() {fmt.Println("链表为空")return nil}currentNode := list.headNodeif currentNode.Next == nil && currentNode.Prev == nil {list.headNode = nilreturn currentNode.Data}list.headNode = currentNode.NextcurrentNode.Prev = nilreturn currentNode.Data
}//删除链表尾结点
func (list *List) RemoveLastNode() Object {if list.IsEmpty() {fmt.Println("链表为空")return nil}if list.headNode.Next == nil {list.headNode = nil}currentNode := list.headNodefor currentNode.Next != nil {currentNode = currentNode.Next}currentNode.Prev.Next = nilreturn currentNode.Prev.Data
}//删除双向表中指定值的结点
func (list *List) Remove(data Object)  {if list.IsEmpty() {fmt.Println("链表为空")return}currentNode := list.headNodeif list.headNode.Next == nil && list.headNode.Data == data {list.headNode = nil}fmt.Println(data, currentNode.Data, currentNode.Data == data)for currentNode != nil {if currentNode.Data == data && currentNode == list.headNode {list.headNode = currentNode.Next} else if currentNode.Data == data && currentNode.Prev != nil {currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prev} else {currentNode = currentNode.Next}}
}//删除双向链表中指定位置的结点
func (list *List) RemovePosition(position int) {if list.IsEmpty() {fmt.Println("链表为空")return}if position <=1 {list.RemoveHeadNde()} else if position > list.Length() {list.RemoveLastNode()} else {currentNode := list.headNodecount := 1for count != position {count++currentNode = currentNode.Next}currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prev}
}//查询双向链表中是否包含某一个结点(和单向链表一样)
func (list *List) Contain(data Object) bool {if list.IsEmpty() {fmt.Println("链表为空")return false}currentNode := list.headNodefor currentNode != nil {if currentNode.Data == data {return true}currentNode = currentNode.Next}return false
}

entry.go(测试)

package mainimport ("fmt""learnGo/linkedList/doublyLinkedList"
)func print(list doublyLinkedList.List)  {fmt.Printf("链表长度%dn", list.Length())fmt.Println("遍历链表所有结点:")list.Traverse()fmt.Println()fmt.Println()
}func main() {list := doublyLinkedList.List{}fmt.Println("++++++++1、判断链表是否为空++++++++")fmt.Printf("链表是否为空:%v", list.IsEmpty())fmt.Println()fmt.Println()fmt.Println("++++++++2、向双向链表头部添加元素++++++++")fmt.Println()list.AddFromHead(1)list.AddFromHead(2)list.AddFromHead(3)print(list)fmt.Println("++++++++3、向双向链表尾部添加元素++++++++")fmt.Println()list.Append("Golang")list.Append("PHP")list.Append("Java")print(list)fmt.Println("++++++++4、向双向链表的指定位置插入结点++++++++")fmt.Println("++++++++(1)向双向链表的【第一个】位置插入结点++++++++")list.Insert(1, "First")print(list)fmt.Println("++++++++(2)向双向链表的【第三个】位置插入结点++++++++")list.Insert(3, "Third")print(list)fmt.Println("++++++++(3)向双向链表的【最后】位置插入结点++++++++")list.Insert(list.Length()+1, "Last")print(list)fmt.Println("++++++++5、删除双向链表的头结点++++++++")fmt.Println()list.RemoveHeadNde()print(list)fmt.Println("++++++++6、删除双向链表的尾结点++++++++")fmt.Println()list.RemoveLastNode()print(list)fmt.Println("++++++++7、删除双向表中指定值的结点++++++++")list.Remove(3)//这里的类型要和你插入时的类型一致(弱类型语言写习惯了,很容易忘了)print(list)fmt.Println("++++++++8、删除双向表中指定位置的结点++++++++")fmt.Println("++++++++(1)删除双向链表的【第一个】位置结点++++++++")list.RemovePosition(1)print(list)fmt.Println("++++++++(2)删除双向链表的【第三个】位置结点++++++++")list.RemovePosition(3)print(list)fmt.Println("++++++++(3)删除双向链表的【最后】位置结点++++++++")list.RemovePosition(list.Length())print(list)fmt.Println("++++++++9、查询双向链表中是否包含某一个结点++++++++")fmt.Println()fmt.Printf("是否存在Golang结点:%vn", list.Contain(2))
}

双向循环链表

doublyLoopLinkedList.go

package doublyLoopLinkedListimport ("fmt"
)type Object interface {}type Node struct {Data ObjectPrev,Next *Node
}type List struct {headNode *Node
}//判断双向循环链表是否为空
func (list *List) IsEmpty() bool {if list.headNode == nil {return true}return false
}//遍历双向循环链表
func (list *List) Traverse() {if list.IsEmpty() {fmt.Println("链表为空")return}if list.headNode.Next == nil {//兼容双向循环链表只有一个结点的情况fmt.Printf("%vt", list.headNode.Data)return}currentNode := list.headNodefor currentNode.Next != list.headNode {fmt.Printf("%vt", currentNode.Data)currentNode = currentNode.Next}fmt.Printf("%vt", currentNode.Data)
}//获取双向循环链表的长度
func (list *List) Length() int {if list.IsEmpty() {return 0}count := 1currentNode := list.headNodefor currentNode.Next != list.headNode {count++currentNode = currentNode.Next}return count
}//从双向循环链表头部添加结点(一定一定要画图,比较好理解)
func (list *List) AddFromHead(data Object) *Node {node := &Node{Data: data}if list.IsEmpty() {list.headNode = nodereturn node}currentNode := list.headNodeif currentNode.Next == nil { //考虑只有一个节点的时候node.Prev = currentNodecurrentNode.Next = nodenode.Next = currentNodecurrentNode.Prev = nodelist.headNode = nodereturn node}node.Prev = currentNode.PrevcurrentNode.Prev.Next = nodecurrentNode.Prev = nodenode.Next = currentNodelist.headNode = nodereturn node
}//从双向循环链表尾部添加结点
func (list *List) Append(data Object) *Node {node := &Node{Data: data}if list.IsEmpty() {list.headNode = nodereturn node}currentNode := list.headNodecurrentNode.Prev.Next = nodenode.Prev = currentNode.PrevcurrentNode.Prev = nodenode.Next = currentNodereturn node
}//向双向循环链表的指定位置插入结点
func (list *List) Insert(position int, data Object) {if position <=1 {list.AddFromHead(data)} else if position > list.Length() {list.Append(data)} else {node := &Node{Data: data}currentNode := list.headNodecount := 1for count != position {count++currentNode = currentNode.Next}//将待插入的节点插入到当前节点的前边即可(这块的逻辑其实和双向链表的在中间位子插入结点逻辑一样)currentNode.Prev.Next = nodenode.Prev = currentNode.PrevcurrentNode.Prev = nodenode.Next = currentNode}
}//删除双向循环链表头结点
func (list *List) RemoveHeadNde() Object {if list.IsEmpty() {fmt.Println("双向循环链表为空")return ""}currentNode := list.headNodeif currentNode.Next == nil {//只有一个结点的情况list.headNode = nilreturn currentNode.Data}currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prevlist.headNode = currentNode.Nextreturn currentNode.Data
}//删除双向循环链表尾结点
func (list *List) RemoveLastNode() Object {if list.IsEmpty() {fmt.Println("双向循环链表为空")return ""}currentNode := list.headNodeif currentNode.Next == nil {//只有一个结点的情况list.headNode = nilreturn list.headNode.Data}lastNode := list.headNode.PrevlastNode.Prev.Next = currentNodecurrentNode.Prev = lastNode.Prevreturn lastNode.Data
}//删除双向循环链表中指定值的结点
func (list *List) Remove(data Object) bool {if list.IsEmpty() {fmt.Println("双向循环链表为空")return false}//如果链表只有一个节点if list.headNode.Next == nil {if list.headNode.Data == data {list.headNode = nilreturn true}return false}currentNode := list.headNode//如果值刚好等于第一个节点的值if currentNode.Data == data {list.RemoveHeadNde()return true}//如果值刚好等于最后一个结点的值for currentNode.Next != list.headNode {if currentNode.Data == data {//删除中间节点currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prevreturn true} else {currentNode = currentNode.Next}}if currentNode.Data == data { //刚好是最后一个结点的时候list.RemoveLastNode()return true}return false
}//删除双向循环链表中指定位置的结点
func (list *List) RemovePosition(position int) {if list.IsEmpty() {fmt.Println("双向循环链表为空")return}if position <= 1 {list.RemoveHeadNde()} else if position > list.Length() {list.RemoveLastNode()} else {currentNode := list.headNodecount := 1for count != position {count++currentNode = currentNode.Next}currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prev}
}//查询双向循环链表中是否包含某一个结点(跟循环链表的查找逻辑一样)
func (list *List) Contain(data Object) bool {if list.IsEmpty() {fmt.Println("双向循环链表为空")return false}currentNode := list.headNodefor currentNode.Next != list.headNode {if currentNode.Data == data {return true}currentNode = currentNode.Next}if currentNode.Data == data {return true}return false
}

entry.go

package mainimport ("fmt""learnGo/linkedList/doublyLoopLinkedList"
)func print(list doublyLoopLinkedList.List)  {fmt.Printf("链表长度%dn", list.Length())fmt.Println("遍历链表所有结点:")list.Traverse()fmt.Println()fmt.Println()
}func main() {list := doublyLoopLinkedList.List{}fmt.Println("++++++++1、判断链表是否为空++++++++")fmt.Printf("链表是否为空:%v", list.IsEmpty())fmt.Println()fmt.Println()fmt.Println("++++++++2、向双向循环链表头部添加结点++++++++")fmt.Println()list.AddFromHead(1)list.AddFromHead(2)list.AddFromHead(3)print(list)fmt.Println("++++++++3、向双向循环链表尾部添加结点++++++++")fmt.Println()list.Append("lastNode")print(list)fmt.Println("++++++++4、向双向循环链表指定位置添加结点++++++++")fmt.Println()list.Insert(1,"firstNode")print(list)fmt.Println("++++++++5、删除双向循环链表头结点++++++++")fmt.Println()list.RemoveHeadNde()print(list)fmt.Println("++++++++6、删除双向循环链表尾结点++++++++")fmt.Println()list.RemoveLastNode()print(list)fmt.Println("++++++++7、删除双向循环链表中指定值的结点++++++++")fmt.Println()list.Remove(1)print(list)fmt.Println("++++++++8、删除双向循环链表中指定位置的结点++++++++")fmt.Println()list.RemovePosition(list.Length()-1)print(list)fmt.Println("++++++++9、查询双向循环链表中是否包含某一个结点++++++++")fmt.Println()fmt.Println("是否包含值为firstNode的结点:", list.Contain("firstNode"))print(list)
}

小白一枚,记录点滴成长,公众号:IT猿圈

主要记录:操作系统、计算机网络、编译原理、数据结构和算法

参考: 《数据结构与算法之美》

http://www.lbrq.cn/news/1480411.html

相关文章:

  • jsp语言做网站/域名检测查询
  • 网站升级停止访问如何做/百度站长平台账号购买
  • 网站开发运行环境/互联网运营自学课程
  • 教育网站开发用例图/百度蜘蛛池自动收录seo
  • 免费可商用素材网站/公司网站搭建流程
  • php网站后台建设/防疫优化措施
  • 网站里怎样做物流跟踪功能/推广软件
  • 广州网站建设出售/滴滴友链
  • 手机网站设计公司哪家专业/优化网站技术
  • 黄石网站建设公司/域名大全
  • 什么是做自己的网站/百家联盟推广部电话多少
  • 网站开发日志文档/黑帽seo技术论坛
  • html5培训网站模板/百度网盘搜索引擎
  • 做这种灰色的网站犯法/如何做网页
  • 类似源码之家的网站/百度做推广一般要多少钱
  • 如何做英文网站外链/深圳网络营销怎么推广
  • 广州一建筑外墙脚手架坍塌/网站排名怎么优化
  • b2b网站有哪些模块/宁波建站模板系统
  • 做图素材网站/网站运营方案
  • 磁力天堂/天津百度搜索排名优化
  • 网站大数据怎么做/群站优化之链轮模式
  • 免费博客网站/开发网站需要多少钱
  • 网站建设行业研究/百度关键词规划师
  • 做网站的技术支持/百度导航下载安装手机导航
  • 宁波网站建设公司地址/视频号视频怎么看下载链接
  • 上海做网站的哪家好/搭建网站平台
  • 建站一条龙/互联网营销师是干什么
  • 绵阳手机网站制作/网站内部seo
  • 杭州网站建设宣盟网络/职业教育培训机构排名前十
  • 事业单位网站建设计划/电商代运营一般收多少服务费
  • 因为想开发新项目了~~要给老Python项目整个虚拟环境
  • k8s-master03加入集群失败解决方法之一
  • Dify 从入门到精通(第 4/100 篇):快速上手 Dify 云端:5 分钟创建第一个应用
  • 力扣热题100-------74.搜索二维矩阵
  • 【网络工程师软考版】路由协议 + ACL
  • Wndows Docker Desktop-Unexpected WSL error错误