SinceNow.net

go 链表

Go实现链表操作

phpangel   2022-07-07 13:22:49

本文试着采用go语言实现了一个带头指针的链表,包括尾部添加数据,头部添加数据,根据索引删除数据,根据索引查找数据,后续功能陆续完善。

由于go语言语法简化,用go语言实现链表更加方便快捷,代码更加精炼简洁。代码如下:

定义结构体

package main

import "fmt"
//节点结构体
type Node struct {
    data interface{}
    next *Node
}
//声明一个链表
type NodeList struct {
    headNode *Node
}

尾部插入数据,尾插法

//在末尾增加数据,尾插法
func (this *NodeList) addAf(data interface{}) {
    node := Node{data: data, next: nil}
    if this.headNode == nil {
        this.headNode = &node
    } else {
        tmp := this.headNode
        for tmp.next != nil {
            tmp = tmp.next
        }
        tmp.next = &node
    }
}

头部插入数据,头插法

//在头部增加数据
func (this *NodeList) addPre(data interface{}) {
    node := Node{data: data, next: nil}
    if this.headNode == nil {
        this.headNode = &node
    } else {
        tmp := this.headNode
        this.headNode = &node
        node.next = tmp
    }
}

根据索引删除数据

//根据索引删除数据
func (this *NodeList) delete(index int) bool {
    if this.headNode == nil {
        fmt.Println("no data")
        return false
    } else {
        tmp := this.headNode
        curr := tmp
        for i := 0; i < index-1; i++ {
            if tmp == nil {
                fmt.Println("索引越界")
                return false
            }
            curr = tmp
            tmp = tmp.next
        }
        q := curr.next
        curr.next = q.next
        return true
    }
}

根据索引查找数据

//根据索引查找
func (this *NodeList) serach(index int) (interface{}, bool) {
    if this.headNode == nil {
        fmt.Println("no data")
        return 0, false
    } else {
        //临时指针,用来后移遍历
        tmp := this.headNode
        //当前指示指针
        curr := this.headNode
        for i := 0; i < index; i++ {
            if tmp == nil {
                fmt.Println("索引越界")
                return 0, false
            }
            curr = tmp
            tmp = tmp.next
        }
        //return tmp.data, true
        return curr.data, true
    }
}

遍历链表,打印所有数据

func (this *NodeList) showall() {
    if this.headNode == nil {
        fmt.Println("no data")
    } else {
        tmp := this.headNode
        for tmp.next != nil {
            fmt.Println(tmp.data)
            tmp = tmp.next
        }
        fmt.Println(tmp.data)
    }
}

主函数

1、对于引用类型的变量,我们不光要声明它,还要为它分配内容空间,否则我们的值放在哪里去呢?

2、对于值类型的声明不需要,是因为已经默认帮我们分配好了

3、通过new分配内存空间,同时把分配的内存置为零,也就是类型的零值,并返回它的地址,此时得到一个链表的头指针

4、go是带垃圾回收的,没有C语言中的malloc和free,内存释放由系统来执行

func main() {
    //对于引用类型的变量,我们不光要声明它,还要为它分配内容空间,否则我们的值放在哪里去呢?
    //对于值类型的声明不需要,是因为已经默认帮我们分配好了
    //通过new分配内存空间,同时把分配的内存置为零,也就是类型的零值,并返回它的地址,此时得到一个链表的头指针
    //go是带垃圾回收的,没有C语言中的malloc和free,内存释放由系统来执行
    var nl = new(NodeList)
    nl.addAf("hello1")
    nl.addAf("hello2")
    nl.addAf("hello3")
    nl.addAf("hello4")
    nl.addAf("hello5")
    nl.addAf("hello6")
    nl.addAf("hello7")
    nl.addPre("hello8")
    nl.addPre("hello9")
    fmt.Println("打印所有数据:")
    nl.showall()
    fmt.Println("查找索引为9的数据:")
    data1, ok := nl.serach(9)
    if ok {
        fmt.Println(data1)
    }
    fmt.Println("查找索引为10的数据:")
    data2, ok := nl.serach(10)
    if ok {
        fmt.Println(data2)
    }
    fmt.Println("查找索引为5的数据:")
    data3, ok := nl.serach(5)
    if ok {
        fmt.Println(data3)
    }
    fmt.Println("删除索引为5的数据:")
    result := nl.delete(5)
    if result {
        fmt.Println("删除成功:")
    }
    fmt.Println("再次打印所有数据:")
    nl.showall()
}

运行结果如下:

打印所有数据:
hello9
hello8
hello1
hello2
hello3
hello4
hello5
hello6
hello7
查找索引为9的数据:
hello7
查找索引为10的数据:
索引越界
查找索引为5的数据:
hello3
删除索引为5的数据:
删除成功:
再次打印所有数据:
hello9
hello8
hello1
hello2
hello4
hello5
hello6
hello7

go 链表

0 Comments

message
沪ICP备2024072411号 © 2022 SinceNow.net - GitHub
Login