__ __ .__ __. __ ___ _______ _______ __ __ _______.___________.
| | | | | \ | | | |/ / | ____|| \ | | | | / | |
| | | | | \| | | ' / | |__ | .--. | | | | | | (----`---| |----`
| | | | | . ` | | < | __| | | | | | | | | \ \ | |
| `----.| | | |\ | | . \ | |____ | '--' | | `----.| | .----) | | |
|_______||__| |__| \__| |__|\__\ |_______||_______/ |_______||__| |_______/ |__|
在上一章中我們學習了隊列以及相關的基本操作,并有數組切片和鏈表兩種不同的實現方式,本章我們將對鏈表進行單獨介紹。
如果我們需要存儲操作一系列的數據,使用數組(或列表)是最常用的數據結構。但是在大多數編程語言中數組的長度是固定的(雖然Go有切片),如果我們使用數組存取數據,遇到需要移動數據的操作其實成本是很高的,有時候也會碰到浪費大量內存的情況。使用鏈表可以解決這些問題。
本章內容包括:
- 鏈表數據結構
- 向鏈表添加元素
- 從鏈表移除元素
- 雙向鏈表
- 循環鏈表
- 排序鏈表
- 通過鏈表實現棧
鏈表定義
鏈表主要包含以下接口:
- Push(e ...Element):向鏈表尾部添加若干新元素
- Insert(element Element, position int):在指定位置插入元素
- GetElementAt(index int) Element:獲取特定位置元素
- Remove(element Element):刪除特定元素
- RemoveAt(position int):刪除特定位置元素
- IndexOf(element Element) int:返回特定元素索引
- Size() int:返回鏈表包含元素個數
- IsEmpty() bool:若鏈表為空返回 true
type Element interface {
}
type List interface {
// 向鏈表尾部添加若干新元素
Push(e ...Element)
// 在指定位置插入元素
Insert(element Element, position int)
// 獲取特定位置元素
GetElementAt(index int) Element
// 刪除特定元素
Remove(element Element)
RemoveAt(position int)
// 返回特定元素索引
IndexOf(element Element) int
// 返回鏈表包含元素個數
Size() int
// 若鏈表為空返回 true
IsEmpty() bool
}
type Node struct {
Value Element
Next *Node
}
type LinkedList struct {
Head *Node
size int
}
向鏈表尾部添加元素
// 在末端插入若干新元素
func (s *LinkedList) Push(e ...Element) {
iter := s.Head
for _, v := range e {
node := &Node{
Value: v,
Next: nil,
}
for iter.Next != nil {
iter = iter.Next
}
// 此時iter為最后一項
iter.Next = node
s.size++
}
}
向鏈表指定位置插入元素
// 在指定位置插入新元素
func (s *LinkedList) Insert(element Element, position int) {
if position > s.Size()-1 {
return
}
iter := s.Head
for step := position; step > 0; step-- {
iter = iter.Next
}
node := &Node{
Value: element,
Next: iter.Next,
}
iter.Next = node
s.size++
}
從鏈表中移除元素
// 刪除指定元素
func (s *LinkedList) Remove(element Element) {
last := s.Head
for iter := s.Head; iter.Next != nil; iter = iter.Next {
if iter.Value == element {
last.Next = iter.Next
return
}
last = iter
}
}
// 刪除指定位置的元素
func (s *LinkedList) RemoveAt(position int) {
if position > s.Size()-1 {
return
}
iter := s.Head
last := s.Head
for step := position; step > 0; step-- {
last = iter
iter = iter.Next
}
last.Next = iter.Next
s.size--
}
IsEmpty方法和Size方法
// 鏈表大小
func (s *LinkedList) Size() int {
return s.size
}
// 鏈表是否為空
func (s *LinkedList) IsEmpty() bool {
return s.Size() == 0
}
完整實現
package main
import "fmt"
type Element interface {
}
type List interface {
// 向鏈表尾部添加若干新元素
Push(e ...Element)
// 在指定位置插入元素
Insert(element Element, position int)
// 獲取特定位置元素
GetElementAt(index int) Element
// 刪除特定元素
Remove(element Element)
RemoveAt(position int)
// 返回特定元素索引
IndexOf(element Element) int
// 返回鏈表包含元素個數
Size() int
// 若鏈表為空返回 true
IsEmpty() bool
}
type Node struct {
Value Element
Next *Node
}
type LinkedList struct {
Head *Node
size int
}
// 在末端插入若干新元素
func (s *LinkedList) Push(e ...Element) {
iter := s.Head
for _, v := range e {
node := &Node{
Value: v,
Next: nil,
}
for iter.Next != nil {
iter = iter.Next
}
// 此時iter為最后一項
iter.Next = node
s.size++
}
}
// 在指定位置插入新元素
func (s *LinkedList) Insert(element Element, position int) {
if position > s.Size()-1 {
return
}
iter := s.Head
for step := position; step > 0; step-- {
iter = iter.Next
}
node := &Node{
Value: element,
Next: iter.Next,
}
iter.Next = node
s.size++
}
// 返回指定位置的元素
func (s *LinkedList) GetElementAt(index int) Element {
if index > s.Size()-1 {
return nil
}
iter := s.Head
for step := index; step > -1; step-- {
iter = iter.Next
}
return iter.Value
}
// 刪除指定元素
func (s *LinkedList) Remove(element Element) {
last := s.Head
for iter := s.Head; iter.Next != nil; iter = iter.Next {
if iter.Value == element {
last.Next = iter.Next
return
}
last = iter
}
}
// 刪除指定位置的元素
func (s *LinkedList) RemoveAt(position int) {
if position > s.Size()-1 {
return
}
iter := s.Head
last := s.Head
for step := position; step > 0; step-- {
last = iter
iter = iter.Next
}
last.Next = iter.Next
s.size--
}
// 獲取指定元素位置
func (s *LinkedList) IndexOf(element Element) int {
idx := -1
iter := s.Head
for iter.Next != nil {
idx++
iter = iter.Next
if iter.Value == element {
return idx
}
}
return -1
}
// 鏈表大小
func (s *LinkedList) Size() int {
return s.size
}
// 鏈表是否為空
func (s *LinkedList) IsEmpty() bool {
return s.Size() == 0
}
func NewLinkedList() List {
return &LinkedList{
Head: &Node{},
size: 0,
}
}
func main() {
list := NewLinkedList()
fmt.Println("Push:1,2,3,4,5,6,7,8,9")
list.Push(1, 2, 3, 4, 5, 6, 7, 8, 9)
fmt.Println("Size:", list.Size())
fmt.Println("Get idx=8:", list.GetElementAt(8))
fmt.Println("Index of 9:", list.IndexOf(1))
fmt.Println("Insert 20 at 3")
list.Insert(20, 3)
fmt.Println("Get idx=3:", list.GetElementAt(3))
fmt.Println("Remove idx=3: done")
list.RemoveAt(3)
fmt.Println("Get idx=3:", list.GetElementAt(3))
list.Remove(4)
fmt.Println("Remove element=4: done")
fmt.Println("Get idx=3:", list.GetElementAt(3))
}
運行結果
Push:1,2,3,4,5,6,7,8,9
Size: 9
Get idx=8: 9
Index of 9: 0
Insert 20 at 3
Get idx=3: 20
Remove idx=3: done
Get idx=3: 4
Remove element=4: done
Get idx=3: 5
Process finished with exit code 0