單鏈表及雙向連結串列的程式碼實現-golang
阿新 • • 發佈:2021-12-14
單鏈表
package linkedList // 單鏈表的實現 type ListNode struct { Val int Next *ListNode } type MyLinkedList struct { size int head *ListNode } /* // initialize struct func Constructor() MyLinkedList { return MyLinkedList{0, &ListNode{}} } */ func (this *MyLinkedList) Get(index int) int { // 通過索引獲取連結串列節點的值 if index < 0 || index >= this.size { return -1 } // 通過前繼節點獲取 prev := this.head for i:=0;i<index;i++ { prev = prev.Next } return prev.Next.Val } func (this *MyLinkedList) AddAtIndex(index int, val int) { // 通過索引插入節點, 先遍歷找到前繼節點 if index < 0 || index > this.size { return } // 找到前繼節點 prev := this.head for i:=0;i<index;i++ { prev = prev.Next } // 根據給定val生成新節點 node := &ListNode{Val: val} // 防止丟失節點,顯然新節點指向prev的下個節點 node.Next = prev.Next // prev指向新節點 prev.Next = node // 更新size this.size++ } func (this *MyLinkedList) AddAtHead(val int) { // 頭部插入新節點 this.AddAtIndex(0, val) } func (this *MyLinkedList) AddAtTail(val int) { // 尾部插入新節點 this.AddAtIndex(this.size, val) } func (this *MyLinkedList) DeleteAtIndex(index int) { // 通過索引刪除節點, 依然通過前繼節點操作,直接指向下下個節點即可 if index < 0 || index >= this.size { return } // 遍歷找到前繼節點 prev := this.head for i:=0;i<index;i++ { prev = prev.Next } // 前繼指向下下個節點 prev.Next = prev.Next.Next // 更新size this.size-- }
雙向連結串列
//+build ignore package main import "fmt" func main() { head := ConstrutorD() head.AddAtHead(2) head.AddAtHead(5) head.AddAtHead(7) head.AddAtIndex(3,4) head.AddAtTail(100) head.DeleteAtIndex(3) fmt.Println(head.Get(0)) fmt.Println(head.Get(1)) fmt.Println(head.Get(2)) fmt.Println(head.Get(3)) } // 雙向連結串列的實現 type Node struct { Val int Prev, Next *Node } type MyLinkedListD struct { size int head, tail *Node } // initialize struct func ConstrutorD() MyLinkedListD { return MyLinkedListD{} } func (this *MyLinkedListD) Get(index int) int { // 雙向連結串列,根據索引獲取值 if this.size == 0 || index < 0 || index >= this.size { return -1 } // 處理頭尾節點,fast-way if index == 0 { return this.head.Val } if index == this.size - 1 { return this.tail.Val } // 從頭部遍歷到index節點 cur := this.head count := 0 for cur != nil { if count == index { break } count++ cur = cur.Next } return cur.Val } func (this *MyLinkedListD) AddAtIndex(index int, val int) { // 通過索引插入節點 if index > this.size { return } // 小於0,頭部插入 if index <= 0 { this.AddAtHead(val) return } // 尾部插入 if index == this.size { this.AddAtTail(val) return } // 一般情況, 找到index節點 cur := this.head count := 0 for cur != nil && count < index { count++ cur = cur.Next } // 生成新節點, 後繼節點為cur, 前繼節點為cur的前繼節點, // 相當於 cur.prev<---node--->cur node := &Node{Val: val, Next: cur, Prev: cur.Prev} cur.Prev.Next = node // cur的前繼節點的下個節點指向新節點, ---> cur.Prev = node // cur的prev指標指向node, <--- // 更新size this.size++ } func (this *MyLinkedListD) AddAtHead(val int) { // 頭部插入 node := &Node{Val: val} if this.head != nil { node.Next = this.head // 不斷頭部 this.head.Prev = node this.head = node // 更新頭部 } else { // 連結串列為空時 this.head = node this.tail = this.head } // 更新size this.size++ } func (this *MyLinkedListD) AddAtTail(val int) { // 尾部插入 node := &Node{Val: val} if this.tail != nil { node.Prev = this.tail this.tail.Next = node this.tail = node } else { this.tail = node this.head = this.tail } // 更新size this.size++ } func (this *MyLinkedListD) DeleteAtIndex(index int) { // 根據索引刪除節點 if this.size == 0 || index < 0 || index >= this.size { return } if index == 0 { // 更新頭部節點,相當於刪除頭結點 this.head = this.head.Next } else if index == this.size - 1 { // 更新尾部節點,相當於刪除尾部節點 this.tail = this.tail.Prev } else { // 一般情況, 找到刪除節點 cur := this.head count := 0 for cur != nil && count < index { count++ cur = cur.Next } cur.Next.Prev = cur.Prev cur.Prev.Next = cur.Next } this.size-- }