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