**
【数据结构-单链表GO语言实现】
**
主代码 linkedlist.go
package linkedlist
import (
"fmt"
"reflect"
)
//创建链表节点
type Node struct{
Data interface{}
Next *Node
}
//创建链表的头节点
type HeadNode struct{
HeadData int //这里创建了一个特殊的头节点,包含了链表的长度信息
Next *Node
}
//创建可以指向链表的头指针
type List struct{
headpointer *HeadNode
}
//初始化链表(不带头节点的)
//func(this *List) InitNoHeader() *Node{
// return this.headpointer
//}
//初始化链表(带头节点的)这是下面代码主要使用的链表
func(this *List) InitList() *HeadNode{
//这里设置了头节点,其中其数据域存的数据为链表长度
headNode := HeadNode{HeadData: 0, Next: nil}
this.headpointer = &headNode
return this.headpointer
}
//获取链表长度
func(this *List) GetLength() int{
return this.headpointer.HeadData
}
//增 从链表头部插入元素
func(this *List) Push(data interface{}){
//创建新的链表节点
newNode := &Node{Data: data}
newNode.Next = this.headpointer.Next
this.headpointer.Next = newNode
//链表数据增1
this.headpointer.HeadData ++
}
//增 从链表尾部插入元素
func(this *List) Append(data interface{}){
newNode := &Node{Data: data}
if this.GetLength() == 0{
//当链表长度为0时,从头插入与从尾插入没有区别
this.Push(data)
}else{
p := this.headpointer.Next
for p.Next != nil{
p = p.Next
}
p.Next = newNode
this.headpointer.HeadData ++
}
}
//删 从链表头部删除元素
func(this *List) Pop(){
if this.GetLength() ==0{
fmt.Println("ERROR: 该链表为空!")
}else{
p := this.headpointer
p.Next = p.Next.Next
this.headpointer.HeadData --
}
}
//删 从链表尾部删除元素
func(this *List) remove(){
//单链表无法直接获取当前节点的前驱,这里采用的是获取当前链表节点个数来辅助判断最后一个节点的前驱
p := this.headpointer//获取指向头节点的指针
numbers := this.GetLength()
if numbers == 0{
fmt.Println("ERROR: 该链表为空!")
}else if numbers == 1 { //为什么把只有一个节点的情况单独处理,是由于这里设置的头节点和后面的节点数据结构是不一样的,无法统一处理
p.Next = p.Next.Next
p.HeadData --
}else{
per := this.headpointer.Next
for i := 0; i < numbers - 2; i++{
per = per.Next
}
per.Next = per.Next.Next
p.HeadData --
}
}
//查 按值查询
func(this *List) Compare(data interface{}) (*Node, bool){
p := this.headpointer.Next
if this.GetLength() == 0{
fmt.Println("ERROR: 该链表为空!")
}else{
for p.Next != nil && !reflect.DeepEqual(p.Data, data){ //说明: 如果p.Next == nil说明当前p指向的是链表最后一个元素
p = p.Next
}
}
if reflect.DeepEqual(p.Data, data){
return p, true
}else{
return nil, false
}
}
//遍历链表元素
func(this *List) Range(){
p := this.headpointer.Next
for p != nil{ //当p == nil时说明当前链表元素已经遍历完成
fmt.Println(p)
p = p.Next
}
}
测试代码linkedlist_test.go
package linkedlist
import (
"fmt"
"testing"
)
func TestList_GetLength(t *testing.T) {
//创建头指针
list := List{}
//初始化链表
list.InitList()
//list.Pop()
//list.remove()
//fmt.Println(list.GetLength())
list.Push(1)
list.Push(2)
list.Push(3)
list.Push(4)
list.Push(5)
list.Push(6)
//list.remove()
//fmt.Println(list.GetLength())
list.Append(7)
list.Append(8)
list.Append(9)
list.Append(10)
list.remove()
list.Pop()
list.Pop()
fmt.Println(list.GetLength())
node, flag := list.Compare(3)
fmt.Println(node, flag)
list.Range()
}
下一篇将介绍如何使用GO语言实现顺序存储的堆栈数据结构