Golang 操作单向链表的应用实例

代码:

/*
	使用带head头节点的单向链表实现-水浒传英雄排行榜管理:
	1)完成对英雄人物的增删改查操作。
	2)第一种方法:在添加英雄时,直接添加到链表的尾部
	3)第二种方法:在添加英雄时,根据排名将英雄插入到指定位置
	(如果没有这个排名,则添加失败,并给出提示)
*/
package main

import "fmt"

// 定义一个 HeroNode
type HeroNode struct {
	no       int       // 排名
	name     string    // 名字
	nickname string    // 外号
	next     *HeroNode // 下一个节点
}

// 给链表加入一个节点
// 第 1 种插入方式:在单链表的最后插入节点
func InsertHeroNode1(head *HeroNode, newHeroNode *HeroNode) {

	// 先找到该链表的最后一个节点
	// 创建一个辅助节点
	// 辅助节点是用来帮助寻找单向链表的最后一个节点
	temp := head
	for temp.next != nil {
		temp = temp.next // 继续遍历下一个节点
	}

	// 将 newHeroNode 加入到最后一个节点
	temp.next = newHeroNode

}

// 给链表加入一个节点
// 第 2 种插入方式:根据 no ,有序地插入链表
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {

	// 先找到链表中适当的节点
	// 创建一个辅助节点
	// 辅助节点是用来帮助寻找单向链表适当的节点
	temp := head
	var flag bool = true

	// 循环寻找适合插入的节点
	for {

		if temp.next == nil {
			break
		}
		if temp.next.no > newHeroNode.no {
			break
		}

		if temp.next.no == newHeroNode.no {
			flag = false
			break
		}

		// 如果未找到合适的节点,则继续尝试下一个节点
		temp = temp.next

	}

	if flag {
		newHeroNode.next = temp.next
		temp.next = newHeroNode
	} else {
		fmt.Printf(" %d 位置已经有节点\n", temp.next.no)
	}

}

// 删除单向链表的节点
func DelHeroNode(head *HeroNode, id int) {

	temp := head
	var flag bool = false // 是否找得到该id的节点

	for {

		if temp.next == nil {
			break
		}

		if temp.next.no == id {
			flag = true
			break
		}

		temp = temp.next

	}

	if flag {
		temp.next = temp.next.next
	} else {
		fmt.Println("can not find the node")
	}

}

// 遍历单向链表
func ListHeroNode(head *HeroNode) {

	temp := head

	// 先判断该链表是否为空
	if temp.next == nil {
		fmt.Println("empty linked list")
		return
	}

	fmt.Println("链表信息为:")
	// 循环遍历单向链表
	for {
		// 通过前一个节点的索引,打印后一个节点的内容
		fmt.Printf("[%d %s %s] ==> ", temp.next.no, temp.next.name,
			temp.next.nickname)

		temp = temp.next

		if temp.next == nil {
			break
		}

	}

}

func main() {

	// 先创建一个头节点
	head := &HeroNode{}

	// 为第二种插入方式创建头节点 head2
	head2 := &HeroNode{}

	// 创建一个新的 HeroNode
	hero1 := &HeroNode{
		no:       1,
		name:     "宋江",
		nickname: "及时雨",
	}

	hero2 := &HeroNode{
		no:       2,
		name:     "卢俊义",
		nickname: "玉麒麟",
	}

	hero3 := &HeroNode{
		no:       3,
		name:     "吴用",
		nickname: "智多星",
	}

	hero4 := &HeroNode{
		no:       4,
		name:     "公孙胜",
		nickname: "入云龙",
	}

	InsertHeroNode1(head, hero1)
	InsertHeroNode1(head, hero2)
	InsertHeroNode1(head, hero3)
	InsertHeroNode1(head, hero4)

	ListHeroNode(head)

	fmt.Println("\n有序地插入节点============")
	InsertHeroNode2(head2, hero3)
	InsertHeroNode2(head2, hero2)
	InsertHeroNode2(head2, hero1)
	InsertHeroNode2(head2, hero4)

	// 设置 0 号变量,查看是否会按顺序
	hero0 := &HeroNode{
		no:       0,
		name:     "鲁路修",
		nickname: "ZERO",
	}
	InsertHeroNode2(head2, hero0)

	// 设置 no 重复的变量测试
	hero33 := &HeroNode{
		no:       3,
		name:     "有用",
		nickname: "智少星",
	}
	InsertHeroNode2(head2, hero33)

	// 设置 99 号变量,测试
	hero99 := &HeroNode{
		no:       99,
		name:     "刹那 F 清英",
		nickname: "能天使",
	}
	InsertHeroNode2(head2, hero99)

	ListHeroNode(head2)

	DelHeroNode(head2, 0)
	fmt.Println("\n删除了节点后的链表为============")
	ListHeroNode(head2)

}

输出结果:

链表信息为:
[1 宋江 及时雨] ==> [2 卢俊义 玉麒麟] ==> [3 吴用 智多星] ==> [4 公孙胜 入云龙] ==> 
有序地插入节点============
 3 位置已经有节点
链表信息为:
[0 鲁路修 ZERO] ==> [1 宋江 及时雨] ==> [2 卢俊义 玉麒麟] ==> [3 吴用 智多星] ==> [4 公孙胜 入云龙] ==> [99 刹那 F 清英 能天使] ==> 
删除了节点后的链表为============
链表信息为:
[1 宋江 及时雨] ==> [2 卢俊义 玉麒麟] ==> [3 吴用 智多星] ==> [4 公孙胜 入云龙] ==> [99 刹那 F 清英 能天使] ==>

小结:

该代码包含了使用Go语言操作单向链表的一系列基础操作:

1)无序地插入单向链表:

func InsertHeroNode1(head *HeroNode, newHeroNode *HeroNode)

2)根据内容编号,有序地插入单向链表:

func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode)

3)删除单向链表的指定节点:

func DelHeroNode(head *HeroNode, id int)

4)显示完整的单向链表:

func ListHeroNode(head *HeroNode)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值