单链表(Go)

链表介绍:
    链表是有序的列表;
 
    单链表:
        一般来说,为了比较好的对单链表进行增删改查的操作,我们都会给他设置一个头节点,头节点的作用是用来标识单链表头部,不存放任何数据;
 
  
案例说明:
        单向链表实现 --增删改查
 
代码实现
package main

import (
	"fmt"
)

// 单项链表的 增删改查

// 定义一个HeroNode结构体管理单向链表
type HeroNode struct {
	no int 
	name string 
	nickname string 
	next  *HeroNode  // 表示指向下一个节点
}

// 给链表插入一个节点
// 编写第一种插入函数,在单链表最后加入
func InsertHeroNode(head *HeroNode, newHeroNode *HeroNode) {
	// 思路
	//1.先找到该链表的最后节点
	//2.创建一个辅助节点
	temp := head 
	for {
		if temp.next == nil {  // 表示找到最后一个
			break 
		}
		temp = temp.next  // 让temp不断地指向下一个节点
	}

	//3.将newHeroNode 加入到链表地最后
	temp.next = newHeroNode
}

// 编写第2种插入函数,根据no 的编号从小到大插入
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {
	// 思路
	//1.先找到该链表的最后节点
	//2.创建一个辅助节点
	temp := head 
	flag := true 
	// 让插入新英雄的节点的no  和temp的下一个节点的no比较
	for {
		if temp.next == nil {  // 表示找到最后一个
			break 
		}else if temp.next.no >= newHeroNode.no { // 如果允许有相同的编号
			// newHeroNode 应该插入到temp后面
			break 
		}else if temp.next.no == newHeroNode.no {
			// 排行榜这里编号不可以重复,所以不能插入
			flag = false
			break 
		}
		temp = temp.next
	}

	//3.将newHeroNode 加入到链表里
	if !flag {
		fmt.Printf("insert err, no=%d is exists 
", newHeroNode.no)
	}else {
		// 重点 先让 newHeroNode.next 的next 指向 temp.next 不然就会出问题,导致链表断开
		newHeroNode.next = temp.next 
		temp.next = newHeroNode
	}
}

// 删除链表的一个节点
func DelHeroNode(head *HeroNode, no int) {
	temp := head 
	flag := false
	// 要删除no  和temp的下一个节点的no比较
	for {
		if temp.next == nil {
			break 
		}else if temp.next.no == no {
			flag = true 
			break 
		}
		temp = temp.next
	}

	if flag {
		temp.next = temp.next.next
	}else {
		fmt.Printf("sorry no=%d not exists!", no)
	}
}

// 更新链表里的某个节点信息
func UpdateHeroNode(head *HeroNode, no int, newHeroNode *HeroNode) {
	temp := head 
	flag := false 
	for {
		if temp.next == nil {
			break 
		}else if temp.next.no == no {
			flag = true 
			break 
		}
		temp = temp.next 
	}

	if flag {
		newHeroNode.next = temp.next.next 
		temp.next = newHeroNode
	}else {
		fmt.Printf("sorry no=%d not exists~~ 
", no)
	}
}

// 显示链表地所有节点信息
func ListHeroNode(head *HeroNode) {
	//1.借助一个辅助点
	temp := head 

	// 遍历之前先判断此链表是否是空链表
	if temp.next == nil {
		fmt.Println("Link empty~~~")
		return 
	}
	//2.遍历链表
	for {
		fmt.Printf("[%d, %s, %s]-->", temp.next.no, temp.next.name, temp.next.nickname)
		// 判断是否为链表尾部了
		temp = temp.next 
		if temp.next == nil {
			break
		}
	}
	fmt.Println()

}

func main() {
	// 1.先创建一个头节点
	head := &HeroNode{}

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

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

	hero3 := &HeroNode{
		no : 3,
		name : "林冲",
		nickname : "豹子头",
	}

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

	//3.先加入
	// 第一种方式添加 --> no顺序保证不了
	// InsertHeroNode(head, hero3)
	// InsertHeroNode(head, hero1)
	// InsertHeroNode(head, hero2)
	// 第二种方式插入
	InsertHeroNode2(head, hero3)
	InsertHeroNode2(head, hero1)
	InsertHeroNode2(head, hero2)
	// InsertHeroNode2(head, hero4)

	//4.显示链表
	ListHeroNode(head)

	//5.删除节点
	DelHeroNode(head, 1)
	ListHeroNode(head)
	DelHeroNode(head, 3)
	ListHeroNode(head)
	
	// 6.更新节点
	fmt.Println("更新后-----------------")
	nhero2 := &HeroNode{
		no : 2,
		name : "吴用",
		nickname : "智多星",
	}
	UpdateHeroNode(head, 2, nhero2)
	ListHeroNode(head)
}

  

原文地址:https://www.cnblogs.com/guo-s/p/14278677.html