golang实现单向链表
单向链表介绍
单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的。单向链表的每个元素称为一个结点,每个结点可以在内存的任意位置,结点包含数据域和指针域。数据域是结点中存储数据元素的部分。指针域是下一个结点地址的部分。
头指针
在单向链表中,第一个结点前面是没有前驱结点的,他是整个链表的开始地址,如果想操作该节点,必须有一个指针变量指向该节点,这个指针变量称为头指针。
头指针具有标识作用,所以常用头指针冠以链表的名字。对单链表的存取必须从头指针开始进行,由于单链表的最后一个结点没有直接后继,则指针为NULL。
头结点
为了统一操作,使操作第一个元素节点为空的时候头指针不是一个空指针,经常在链表第一个结点前加入一个头结点,头结点和其他节点类型一样,但数据域一般无意义。在有些时候,头结点的数据域可以放置整个链表的信息,例如可以存放整个链表的长度。
头指针指向头结点,而头结点的指针域指向第一个有效结点。
头指针是链表的必要元素,头结点则不是链表所必需的
golang实现单向链表
package main
import (
"fmt"
"testing"
)
//定义结点的结构体
type LinkNode struct {
Data interface{} //数据域
Next *LinkNode //指针域
}
//定义链表结构体
type LinkList struct {
HeadPointer *LinkNode //头结点
}
//创建一个结点
func NewLinkNode(v interface{}) *LinkNode {
return &LinkNode{v, nil}
}
//创建头指针
func NewLinkList() *LinkList {
//创建头结点,使用头结点的数据域保存链表长度
headPointer := &LinkNode{
Data: 0,
Next: nil,
}
return &LinkList{headPointer}
}
//获取链表长度
func(linkList *LinkList) GetListLength() int {
return linkList.HeadPointer.Data.(int)
}
//链表长度自增
func (linkList *LinkList)incListLength() {
linkList.HeadPointer.Data = linkList.HeadPointer.Data.(int) + 1
}
//链表长度自增
func (linkList *LinkList)decListLength() {
linkList.HeadPointer.Data = linkList.HeadPointer.Data.(int) - 1
}
//往链表末尾追加结点
func (linkList *LinkList)AppendNode(v interface{}) {
newNode := NewLinkNode(v)
cuutentNode := linkList.HeadPointer
for cuutentNode.Next != nil {
cuutentNode = cuutentNode.Next
}
cuutentNode.Next = newNode
linkList.incListLength()
}
//在链表指定位置添加结点
func (linkList *LinkList) Insert(i int, v interface{}) {
newNode := NewLinkNode(v)
cuutentNode := linkList.HeadPointer
//将前一个结点的指针域存在本结点的指针域中,
//将新结点的地址写入前一个结点的指针域中
for j:=0; j<=i; j++ {
if j == i-1 {
newNode.Next = cuutentNode.Next
cuutentNode.Next = newNode
linkList.incListLength()
}
cuutentNode = cuutentNode.Next
}
}
//删除指定节点
func (linkList *LinkList) Remove(v interface{}) {
currentNode := linkList.HeadPointer
//将指定结点的地址在链表去除
for currentNode.Next != nil {
if currentNode.Next.Data == v {
currentNode.Next = currentNode.Next.Next
linkList.decListLength()
}
currentNode = currentNode.Next
}
return
}
//遍历链表
func (linkList *LinkList) Range() {
currentNode := linkList.HeadPointer
fmt.Println("遍历链表开始")
i := 1
for currentNode.Next != nil {
fmt.Printf("node : %d ,data : %v \n" ,i,currentNode.Next.Data)
i++
currentNode = currentNode.Next
}
fmt.Println("遍历链表结束")
}
func TestList(t *testing.T) {
list := NewLinkList()
list.AppendNode("hello 2")
list.AppendNode("hello 3")
list.Insert(1,"hello 1")
list.Range()
list.Remove("hello 1")
list.Range()
}