go语言实现单链表

线性表包含两种存储方法:顺序存储结构和链式存储结构,其中顺序表的缺点是不便插入与删除数据。

单链表:每个结点包含两部分:数据域+指针域,上一个结点的指针指向下一结点,依次相连,形成链表。特别注意的是每个链表必须包含头结点(数据域一般无意义或者为空,有时用来存储链表长度等等)

下面的代码实现链表的基本操作辅助操作,基本操作指的是插入数据、删除数据、查找数据、求链表长度;而辅助操作指的是创建结点、创建(初始化 )链表、判断是否为空链表。和其他语言不同之处是Go语言具有垃圾自动回收的特性,因此不需要释放指针或内存,后续没有用到的变量Go语言会自动回收。

// 单链表:
package main

import "fmt"

// 创建节点结构/类型
type Node struct {
    Data    interface{}
    Next    *Node
}

// 创建链表结构
type LList struct {
    Head    *Node
    Length  int          // 这里的链表长度不计入头节点
}

// a.设计接口:
type Method interface {
    Insert(i int, v interface{})    // 增
    Delete(i int)                   // 删
    GetLength() int                 // 获取长度
    Search(v interface{}) int       // 查
    isNull() bool                   // 判断是否为空
}

// b.初始化函数:
// 创建节点
func CreateNode(v interface{}) *Node {
    return &Node{v, nil}
}
// 创建空链表
func CreateList() *LList {
    return &LList{CreateNode(nil), 0}
}

// c.基于链表结构体实现接口 Method 中的方法:
// 在 i 处插入节点(前插??——即插入到原来的第 i 个节点之前,成为现在的第 i 个节点)
func (list *LList) Insert(i int, v interface{}) {
    s := CreateNode(v)
    pre := list.Head
    for count:=0; count<=i; count++ {
        if count == i-1 {
            s.Next = pre.Next
            pre.Next = s
            list.Length++
        }
        pre = pre.Next
    }    
}
// 删除第 i 处节点
func (list *LList) Delete(i int) {
    pre := list.Head
    for count:=0; count<=i-1; count++ {
        s := pre.Next
        if count == i-1 {
            pre.Next = s.Next
            list.Length--
        }
        pre = pre.Next
    }
}
// 返回链表长度
func (list *LList) GetLength() int {
    return list.Length
}
// 查询值 v 所在的位置
func (list *LList)Search(v interface{}) int {
    pre := list.Head.Next
    for i:=1; i<=list.Length; i++ {
        if pre.Data == v {
            return i
        }
        pre = pre.Next
    }
    return 0
}
// 判空
func (list *LList) isNull() bool {
    pre := list.Head.Next
    if pre == nil {
        return true
    }
    return false
}

// d.设计链表打印输出函数:
func PrintList(list *LList) {
    pre := list.Head.Next
    fmt.Println("LList shows as follows: ...")
    for i:=1; i<=list.Length;i++ {
        fmt.Printf("%v
", pre.Data)
        pre = pre.Next
    }
}

// main 函数:
func main() {
    lList := CreateList()
    fmt.Println("List is null: ", lList.isNull())
var M Method M = lList
// 接口类型的变量可以存储所有实现该接口的类型变量
    M.Insert(1, 3)
    M.Insert(2, 6)
    M.Insert(1, 5)

    PrintList(lList)
    fmt.Println("List length is: ", lList.Length)
    fmt.Println("元素6在位置:", M.Search(6))
    fmt.Println("元素100在位置:", M.Search(100))
    fmt.Println("List is null: ", lList.isNull())

    M.Delete(2)
    PrintList(lList)
    fmt.Println("List length is: ", lList.Length)
}


打印结果:
List is null: true
LList shows as follows: ...
5
3
6
List length is: 3
元素6在位置: 3
元素100在位置: 0
List is null: false
LList shows as follows: ...
5
6
List length is: 2

 

///纵有疾风起,人生不言弃///
原文地址:https://www.cnblogs.com/skzxc/p/11453679.html