---
# System prepended metadata

title: Golang 单链表基本操作
tags: [Golang]

---

# Golang 单链表基本操作
---

```javascript=
单链表是一种链式存取的数据结构，用一组地址任意的存储单元存放线性表中的数据元素。

链表中的数据是以结点来表示的，每个结点的构成：元素(数据元素的映象) + 指针(指示后继元素存储位置)。

元素就是存储数据的存储单元，指针就是连接每个结点的地址数据。
```

:::success
```go=
package main

import "fmt"

//创建结点 结构体
type ListNode struct {
	Value interface{}
	Next  *ListNode
}

//链表 结构体
type LinkList struct {
	Head   *ListNode
	Length int
}

// 创建链表结点
func NewListNode(v interface{}) *ListNode {
	return &ListNode{v, nil}
}

// 获取链表Next域
func (list *ListNode) GetNext() *ListNode {
	return list.Next
}

// 获取链表的Value域
func (list *ListNode) GetValue() interface{} {
	return list.Value
}

// 创建空链表
func NewLinkedList() *LinkList {
        // return &LinkList{NewListNode(nil), 0} 
        // return &LinkList{nil, 0} 
	return &LinkList{NewListNode(0), 0}
}

// 判断链表是否为空
func (list *LinkList) isNulLinkList() bool {
	return list.Head.Next == nil
}

//返回链表长度
func (list *LinkList) GetLength() int {
	return list.Length
}

//打印链表
func (list *LinkList) PrintLinkList() {
	cur := list.Head.Next
	format := ""
	for cur != nil {
		format += fmt.Sprintf("%v", cur)
		cur = cur.Next
		if cur != nil {
			format += "->"
		}
	}

	fmt.Println("LinkList length:", list.GetLength(), "\n", format)
}

//在i处插入节点（前插）
func (list *LinkList) Insert(i int, v interface{}) {
	s := NewListNode(v)
	pre := list.Head
	for count := 1; count <= i; count++ {
		if count == i {
			s.Next = pre.Next
			pre.Next = s
			list.Length++
		}
		pre = pre.Next
	}
}

// 在指定节点后插入数据
func (list *LinkList) InsertAfterNode(p *ListNode, v interface{}) (bool, *ListNode) {
	if p == nil {
		return false, &ListNode{}
	}
	node := NewListNode(v)
	prev := p.Next
	p.Next = node
	node.Next = prev
	list.Length++
	return true, node
}

// 在指定节点前插入数据
func (list *LinkList) InsertBeforeNode(p *ListNode, v interface{}) bool {
	if p == nil || p == list.Head {
		return false
	}
	cur := list.Head.Next
	prev := list.Head
	for cur != nil {
		if cur == p {
			break
		}
		prev = cur
		cur = cur.Next
	}
	if cur == nil {
		return false
	}
	node := NewListNode(v)
	prev.Next = node
	node.Next = cur
	list.Length++
	return true
}

// 表头插入数据
func (list *LinkList) InsertToHead(v interface{}) (bool, *ListNode) {
	return list.InsertAfterNode(list.Head, v)
}

// 表尾插入数据
func (list *LinkList) InsertToTail(v interface{}) (bool, *ListNode) {
	cur := list.Head
	for cur.Next != nil {
		cur = cur.Next
	}
	return list.InsertAfterNode(cur, v)
}

// 删除指定结点
func (list *LinkList) DeleteNodeByNode(p *ListNode) bool {
	if nil == p {
		return false
	}
	cur := list.Head.Next
	pre := list.Head
	for cur != p {
		if cur == nil {
			return false
		}
		pre = cur
		cur = cur.Next
	}
	pre.Next = cur.Next
	list.Length--
	return true
}

// 删除指定位置的节点(从1开始算)
func (list *LinkList) DeleteNodeByIndex1(i int) {
	pre := list.Head
	for count := 1; count < list.Length; count++ {
		s := pre.Next
		if count == i {
			pre.Next = s.Next
			list.Length--
		}
		pre = pre.Next
	}
}

// 删除指定位置的节点
func (list *LinkList) DeleteNodeByIndex2(v int) bool {
	if v > list.Length {
		return false
	}
	cur := list.Head.Next
	pre := list.Head

	for i := 1; i < v; i++ {
		pre = cur
		cur = cur.Next
	}

	pre.Next = cur.Next
	list.Length--

	return true
}

//删除指定位置的节点(从1开始算)
func (list *LinkList) DeleteNodeByIndex3(index int) {
	if index > list.Length {
		return
	} else {
		pre := list.Head
		if index == 1 {
			list.Head = pre.Next
			return
		}
		for i := 1; i < index-1; i++ {
			pre = pre.Next
		}
		pre.Next = pre.Next.Next
		list.Length--
	}
}

//查值v所在位置
func (list *LinkList) Search(key int) int {
	pre := list.Head.Next
	for i := 1; i <= list.Length; i++ {
		if pre.Value == key {
			return i
		}
		pre = pre.Next
	}
	return -1
}

// 通过index查找结点,查找指定位置的结点
func (list *LinkList) FindNodeByIndex(index int) *ListNode {
	if index > list.Length {
		return nil
	}
	cur := list.Head.Next
	for i := 1; i < index; i++ {
		cur = cur.Next
	}
	return cur
}

// 通过index查找结点,查找指定位置的data
func (list *LinkList) FindDataByIndex(index int) interface{} {
	if index > list.Length {
		return nil
	}
	cur := list.Head.Next
	for i := 1; i < index; i++ {
		cur = cur.Next
	}
	return cur.Value
}

// 返回所有结点的内容
func (list *LinkList) AllLinkListData() (data []interface{}) {
	node := list.Head
	if node == nil {
		return nil
	}
	for {
		data = append(data, node.Value)
		if node.Next != nil {
			node = node.Next
		} else {
			break
		}
	}
	return data
}

// 查询链表中是否包含某数据
func (list *LinkList) Contains(data interface{}) bool {
	pre := list.Head.Next
	for i := 1; i <= list.Length; i++ {
		if pre.Value == data {
			return true
		}
		pre = pre.Next
	}
	return false
}

//根据索引更新数据(从1开始算)
func (list *LinkList) UpdateLinkListByIndex(index int, data interface{}) *ListNode {
	if index > list.Length {
		return nil
	}
	cur := list.Head.Next
	for i := 1; i < index; i++ {
		cur = cur.Next
	}
	cur.Value = data
	return cur
}

func main() {
	node := NewListNode(0)
	fmt.Println(node.GetValue())
	fmt.Println(node.GetNext())
	linkList := NewLinkedList()
	fmt.Println("List is Null:", linkList.isNulLinkList())
	fmt.Println("List length is:", linkList.Length)
	var M *LinkList
	M = linkList
	// 添加链表结点数据
	M.Insert(1, 9)
	M.Insert(2, 8)
	M.Insert(1, 7)
	M.Insert(2, 8)
	M.PrintLinkList()
	b1, node1 := M.InsertToHead(3)
	fmt.Println(b1, node1)
	M.PrintLinkList()
	b2, node2 := M.InsertToTail(4)
	fmt.Println(b2, node2)
	M.PrintLinkList()
	M.InsertAfterNode(node1, 1)
	M.PrintLinkList()
	M.InsertBeforeNode(node2, 2)
	M.PrintLinkList()
	b3, node3 := M.InsertToTail(5)
	fmt.Println(b3, node3)
	M.PrintLinkList()
	fmt.Println("List is Null:", linkList.isNulLinkList())
	fmt.Println("List length is:", linkList.GetLength())

	// 查找链表数据
	fmt.Println("元素7在位置  ", M.Search(8))
	fmt.Println("元素10在位置  ", M.Search(10))
	fmt.Println("all link list of data", M.AllLinkListData())
	fmt.Println("链表包含数据5", M.Contains(5))
	fmt.Println("链表位置1的数据为", M.FindDataByIndex(2))
	fmt.Println("链表位置1的结点为", M.FindNodeByIndex(2))

	// 删除链表结点
	fmt.Println("all link list of data", M.AllLinkListData())
	M.PrintLinkList()
	fmt.Println("删除node1", M.DeleteNodeByNode(node1))
	M.PrintLinkList()
	fmt.Println("删除node2", M.DeleteNodeByNode(node2))
	M.PrintLinkList()
	M.DeleteNodeByIndex1(3)
	M.PrintLinkList()
	M.DeleteNodeByIndex2(4)
	M.PrintLinkList()
	M.DeleteNodeByIndex3(5)
	M.PrintLinkList()
	M.DeleteNodeByIndex3(6)
	M.PrintLinkList()
    
        // 更新链表结点
    	M.UpdateLinkListByIndex(1, 2)
	M.PrintLinkList()
	M.UpdateLinkListByIndex(1, 3)
	M.PrintLinkList()
	M.UpdateLinkListByIndex(4, 7)
	M.PrintLinkList()
	M.UpdateLinkListByIndex(5, 7)
	M.PrintLinkList()
}
```
:::

- 结果输出

```go=
0
<nil>
List is Null: true
List length is: 0
LinkedList length: 4 
 &{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 <nil>}
true &{3 0xc000004500}
LinkedList length: 5 
 &{3 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 <nil>}
true &{4 <nil>}
LinkedList length: 6 
 &{3 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000046a0}->&{4 <nil>}
LinkedList length: 7 
 &{3 0xc0000047a0}->&{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000046a0}->&{4 <nil>}
LinkedList length: 8 
 &{3 0xc0000047a0}->&{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000046a0}->&{4 <nil>}
true &{5 <nil>}
LinkedList length: 9 
 &{3 0xc0000047a0}->&{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000046a0}->&{4 0xc0000049c0}->&{5 <nil>}
List is Null: false
List length is: 9
元素7在位置   4
元素10在位置   -1
all link list of data [0 3 1 7 8 9 8 2 4 5]
链表包含数据5 true
链表位置1的数据为 1
链表位置1的结点为 &{1 0xc000004500}
all link list of data [0 3 1 7 8 9 8 2 4 5]
LinkedList length: 9 
 &{3 0xc0000047a0}->&{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000046a0}->&{4 0xc0000049c0}->&{5 <nil>}
删除node1 true
LinkedList length: 8 
 &{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000046a0}->&{4 0xc0000049c0}->&{5 <nil>}
删除node2 true
LinkedList length: 7 
 &{1 0xc000004500}->&{7 0xc000004520}->&{8 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000049c0}->&{5 <nil>}
LinkedList length: 6 
 &{1 0xc000004500}->&{7 0xc0000044c0}->&{9 0xc0000044e0}->&{8 0xc0000048a0}->&{2 0xc0000049c0}->&{5 <nil>}
LinkedList length: 5 
 &{1 0xc000004500}->&{7 0xc0000044c0}->&{9 0xc0000048a0}->&{2 0xc0000049c0}->&{5 <nil>}
LinkedList length: 4 
 &{1 0xc000004500}->&{7 0xc0000044c0}->&{9 0xc0000049c0}->&{5 <nil>}
LinkedList length: 4 
 &{1 0xc000004500}->&{7 0xc0000044c0}->&{9 0xc0000049c0}->&{5 <nil>}
 LinkList length: 4 
 &{2 0xc00005a4c0}->&{7 0xc00005a480}->&{9 0xc00005a980}->&{5 <nil>}
LinkList length: 4 
 &{3 0xc00005a4c0}->&{7 0xc00005a480}->&{9 0xc00005a980}->&{5 <nil>}
LinkList length: 4 
 &{3 0xc00005a4c0}->&{7 0xc00005a480}->&{9 0xc00005a980}->&{7 <nil>}
LinkList length: 4 
 &{3 0xc00005a4c0}->&{7 0xc00005a480}->&{9 0xc00005a980}->&{7 <nil>}
```

###### tags: `Golang`