1. 程式人生 > 實用技巧 >【Go】單鏈表

【Go】單鏈表

node.go

// 連結串列節點
type Node struct {
	data interface{}
	next *Node
}

// 構造一個節點
func NewNode(data interface{}) *Node {
	return &Node{data: data, next: nil}
}

list.go

package single_linked_list

import (
	"fmt"
)

type SingleLinked interface {
	Add(node *Node)                            // 在連結串列前面插入節點
	Append(node *Node)                         // 在連結串列後面插入節點
	Delete(node *Node)                         // 刪除節點
	DeleteByIndex(index int)                   // 根據索引刪除節點
	InsertBefore(data interface{}, node *Node) // 在xx之前插入節點
	InsertAfter(data interface{}, node *Node)  // 在xx之後插入節點
	Get(index int) interface{}
	Length() int
	String() string
}

type List struct {
	head   *Node // 連結串列頭結點
	length int   // 連結串列長度
}

func NewList() *List {
	head := NewNode(nil)
	return &List{head: head, length: 0}
}

// 在連結串列前面插入節點
func (list *List) Add(node *Node) {
	if list.head == nil {
		list.head.next = node
		node.next = nil
		list.length++
	} else {
		temp := list.head     // 儲存頭結點
		node.next = temp.next // 新節點指向的節點就是原先頭結點指向的節點
		temp.next = node      // 頭結點指向新節點
		list.length++
	}
}

// 在連結串列後面插入節點
func (list *List) Append(node *Node) {
	if list.head == nil {
		list.head.next = node
		node.next = nil
		list.length++
	} else {
		temp := list.head
		for temp.next != nil { // 一直迴圈到連結串列最後一個節點
			temp = temp.next
		}
		temp.next = node
		list.length++
	}
}

// 在xx之前插入節點
func (list *List) InsertBefore(data interface{}, node *Node) {
	temp := list.head
	isFind := false
	for temp.next != nil {
		if temp.next.data == data { // 根據data找到其節點,在該節點之前插入新節點
			isFind = true
			break
		}
		temp = temp.next
	}
	if isFind {
		node.next = temp.next
		temp.next = node
		list.length++
	}
}

// 在xx之後插入節點
func (list *List) InsertAfter(data interface{}, node *Node) {
	temp := list.head
	isFind := false
	for temp.next != nil {
		if temp.data == data {
			isFind = true
			break
		}
		temp = temp.next
	}
	if isFind {
		node.next = temp.next
		temp.next = node
		list.length++
	}
}

// 刪除節點
func (list *List) Delete(node *Node) {
	if node == nil {
		return
	}
	temp := list.head
	// 如果下一個節點不等於要刪除的節點,則迴圈找下去
	for temp.next != nil && temp.next != node {
		temp = temp.next
	}
	if temp.next == node {
		// temp指向 要刪除節點指向 的節點
		temp.next = temp.next.next
		list.length--
	}
}

// 根據索引刪除節點
func (list *List) DeleteByIndex(index int) {
	if index > list.length-1 || index < 0 {
		return
	}
	temp := list.head
	for index > 0 {
		temp = temp.next
		index--
	}
	temp.next = temp.next.next
	list.length--

}

func (list *List) Get(index int) interface{} {
	if index > list.length-1 || index < 0 {
		return nil
	}
	temp := list.head
	for index > -1 {
		temp = temp.next
		index--
	}
	return temp.data
}

func (list *List) Length() int {
	return list.length
}

// 列印連結串列
func (list *List) String() string {
	var str string
	node := list.head
	for node.next != nil {
		str += fmt.Sprintf("%v-->", node.next.data)
		node = node.next
	}
	str = fmt.Sprintf("head-->%snil", str)
	return str
}

main.go

func main() {
	var list single_linked_list.SingleLinked = single_linked_list.NewList()
	n1 := single_linked_list.NewNode(1)
	n2 := single_linked_list.NewNode(2)
	n3 := single_linked_list.NewNode(3)
	n4 := single_linked_list.NewNode(4)
	n5 := single_linked_list.NewNode(5)
	list.Add(n1)
	list.Add(n2)
	list.Add(n3)
	list.Append(n4)
	list.Append(n5)
	fmt.Println(list) // head-->3-->1-->2-->nil
	list.Delete(n1)
	fmt.Println(list) // head-->3-->2-->4-->5-->nil
	list.DeleteByIndex(2)
	fmt.Println(list) // head-->3-->2-->5-->nil
	list.InsertBefore(2, n1)
	fmt.Println(list) // head-->3-->1-->2-->5-->nil
	list.InsertAfter(2, n4)
	fmt.Println(list)          // head-->3-->1-->2-->4-->5-->nil
	fmt.Println(list.Length()) // 5
	fmt.Println(list.Get(0))   // 3
	fmt.Println(list.Get(10))  // nil
}