go 連結串列
摘要:package main
import (
"fmt"
"log"
)
// Item 可以理解為範性,也就是任意的資料型別
type Item interface {
}
// 一個節點,除了自身的資料之外,還必須指向下一個節點,尾部節點指向...
package main import ( "fmt" "log" ) // Item 可以理解為範性,也就是任意的資料型別 type Item interface { } // 一個節點,除了自身的資料之外,還必須指向下一個節點,尾部節點指向為nil type LinkNode struct { Payload Item//Payload 為任意資料型別 Next *LinkNode } type LinkNoder interface { // go語言介面,在這個接口裡面,我們可以定義一系列的方法。 Add(payload Item) Delete(index int) Item Insert(index int, payload Item) GetLength() int Search(payload Item) int GetAll(index int) Item Reverse() *LinkNode } // go語言方法,對比與下面的NewLinkNode,方法可以理解為面向物件裡面物件的方法,雖然實現的功能 // 跟函式類似,但是方式是繫結在物件上的,也就是說我們此處的Add是繫結與head這個LinkNode物件的。 // 這個是go語言區別與其他語言的設計方式,也是go語言很重要的一部分。 func (head *LinkNode) Add(payload Item){ // 這裡採用尾部插入的方式,給連結串列新增元素 point := head for point.Next != nil{ point = point.Next } newNode := LinkNode{payload, nil} point.Next = &newNode // 頭部插入 //newNode := LinkNode{payload, nil} //newNode.Next = head } // 刪除元素,並且返回刪除的節點的值 func (head *LinkNode) Delete(index int) Item{ // 邊界條件 linkLength := head.GetLength() if index < 0 || index > linkLength{ fmt.Printf("index out of range %d, please check.", linkLength) return "index out of range, please check." } point := head for i := 0; i<index; i++{ point = point.Next// 移動point到index位置,然後將其next指向next.next } point.Next = point.Next.Next data := point.Next.Payload return data } // 插入元素 func (head *LinkNode) Insert(index int, payload Item){ linkLength := head.GetLength() if index < 0 || index > linkLength{ fmt.Printf("index out of range %d, please", linkLength) return } point := head for i:=0; i<index; i++{ point = point.Next } newNode := LinkNode{Payload:payload} newNode.Next = point.Next point.Next = &newNode } func (head *LinkNode) Search(payload Item) int { point := head index := 0 for point.Next != nil{ if point.Payload == payload{ return index }else { index ++ point = point.Next // 邊界條件 if index > head.GetLength() -1 { break } continue } } // 判斷最後一個元素是否匹配 if point.Payload == payload { return index } return -1// 不存在時的返回值 } func (head *LinkNode) GetLength() int{ iterator := head var length int for iterator.Next != nil{ length ++ iterator = iterator.Next } return length } func (head *LinkNode) GetAll() []Item{ dataList := make([]Item, 0, head.GetLength()) point := head for point.Next != nil{ dataList = append(dataList, point.Payload) point = point.Next } dataList = append(dataList, point.Payload) return dataList } // 建立一個新的連結串列。 函式,對比與上面的方法,函式是沒有繫結任何物件的。 // go語言的函式需要指明引數跟返回值,在此函式中,我們的引數是length,返回值是一個LinkNode物件 // 除了繫結之外,函式跟方法並沒有什麼不同 func NewLinkNode(length int) *LinkNode{ if length <= 0{ fmt.Printf("連結串列長度必須大於0") log.Panic("連結串列長度必須大於0") } var head *LinkNode head = &LinkNode{} for i := 0; i<length; i++{ var newNode *LinkNode newNode = &LinkNode{Payload: i} newNode.Next = head head = newNode } return head } // 迴圈的方式反轉一個連結串列 func (head *LinkNode) Reverse() *LinkNode{ if head == nil || head.Next == nil{ return head } var reverseHead *LinkNode var p *LinkNode reverseHead = head head = head.Next reverseHead.Next = nil p = head.Next for head != nil{ head.Next = reverseHead reverseHead = head head = p if p != nil{ p = p.Next } } return reverseHead } // 遞迴的方式實現連結串列的反轉 func (head *LinkNode) RecursiveReverse() *LinkNode{ if head == nil || head.Next == nil{ return head } second := head.Next newHead := second.RecursiveReverse() second.Next = head head.Next = nil return newHead } func main(){ t := LinkNode{Payload:1,Next:nil} t.Add("123") fmt.Println(t.GetLength()) }