1. 程式人生 > 其它 >單鏈表及雙向連結串列的程式碼實現-golang

單鏈表及雙向連結串列的程式碼實現-golang

單鏈表

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--
}