数据结构与算法:单向链表和环形链表

单向和双向链表的区别就在于单向列表的节点只保存了下个节点的地址,而双向链表中每一个节点保存了上下两个节点的地址

单向链表的增删

package main

import (
	"fmt"
	"os"
)

//todo 这里是单向链表,双向链表需要添加pre这个字段(记录上一个节点的地址)
type HeroNode struct {
	No       int
	Name     string
	NickName string
	Next     *HeroNode // 下一个节点的地址
}

// 链表添加一个节点
//在最后插入
func InsertHeroNode(head *HeroNode, node *HeroNode) {
	tmp := head
	for {
		if tmp.Next == nil {
			break
		}
		tmp = tmp.Next
	}
	tmp.Next = node
}

//在适当的位置插入
func InsertHeroNode2(head *HeroNode, node *HeroNode) {
	tmp := head
	flag := true
	for {
		if tmp.Next == nil {
			break
		} else if tmp.Next.No > node.No {
			break
		} else if tmp.Next.No == node.No {
			flag = false
			break
		}
		tmp = tmp.Next
	}
	if !flag {
		fmt.Println("排名冲突,不准插入")
		return
	} else {
		node.Next = tmp.Next
		tmp.Next = node
	}
}
func ShowHeroNode(head *HeroNode) {
	if head.Next == nil {
		fmt.Println("一团空。。。")
	}
	tmp := head
	for {
		if tmp.Next == nil {
			return
		}
		tmp = tmp.Next
		fmt.Printf("排名:%v ,姓名:%v ,昵称:%v\n", tmp.No, tmp.Name, tmp.NickName)
	}
}
func main() {
	// 头节点
	head := &HeroNode{}
	for {
		var key string
		fmt.Println("1、输入add  添加一名好汉")
		fmt.Println("2、输入get  查看对应排名")
		fmt.Println("3、输入show 显示所有好汉")
		fmt.Println("4、输入exit 退出好汉系统")
		fmt.Print("请输入选项:")
		_, err := fmt.Scanln(&key)
		if err != nil {
			fmt.Println("未知错误:", err, "\t请重新输入")
		}
		switch key {
		case "add":
			var no int
			var name string
			var nickname string
			fmt.Print("请输入排名:")
			_, err := fmt.Scanln(&no)
			if err != nil {
				fmt.Println("未知错误:", err, "\t请重新输入")
			}
			fmt.Print("请输入名字:")
			_, err = fmt.Scanln(&name)
			if err != nil {
				fmt.Println("未知错误:", err, "\t请重新输入")
			}
			fmt.Print("请输入外号:")
			_, err = fmt.Scanln(&nickname)
			if err != nil {
				fmt.Println("未知错误:", err, "\t请重新输入")
			}
			hero1 := &HeroNode{Name: name, No: no, NickName: nickname}
			InsertHeroNode(head, hero1)
		case "show":
			ShowHeroNode(head)
		case "exit":
			os.Exit(0)
		default:
			fmt.Println("请输入正确选项!!!")
		}
	}
}

环形链表的增删

package main

import (
	"fmt"
)

type CircleLinkNode struct {
	No   int
	Name string
	Next *CircleLinkNode
}

func InsertCircleLinkNode(head *CircleLinkNode, node *CircleLinkNode) {
	//如果是空,将node的信息初始化入head节点
	if head.Next == nil {
		head.No = node.No
		head.Name = node.Name
		head.Next = head
		fmt.Printf("排名:%v,名字为:%v 的节点加入成功。。。\n", node.No, node.Name)
		return
	}
	tmp := head
	for {
		if tmp.Next == head {
			break
		}
		tmp = tmp.Next
	}
	//到head前一个,跳出循环,将node的next指向head的地址
	tmp.Next = node
	node.Next = head
	fmt.Printf("排名:%v,名字为:%v 的节点加入成功。。。\n", node.No, node.Name)
}
func DeleteCircleLinkNode(head *CircleLinkNode, No int) {
	//如果是空,不能删除
	if head.Next == nil {
		fmt.Println("空空如也。。。")
		return
	} else if head.Next == head && head.No == No {
		//如果环形链表只有一个节点,且需要删除的是head
		head.Next = nil
		fmt.Printf("排名:%v 的节点删除成功。。。\n", No)
		return
	}
	tmp := head
	flag := false
	for {
		if tmp.Next.No == No && tmp.Next == head {
			head.No = tmp.Next.Next.No
			head.Name = tmp.Next.Next.Name
			head.Next = tmp.Next.Next.Next
			tmp.Next = tmp.Next
			flag = true
			break
		} else if tmp.Next.No == No {
			tmp.Next = tmp.Next.Next
			flag = true
			break
		} else if tmp.Next == head {
			break
		}
		tmp = tmp.Next
	}
	if flag {
		fmt.Printf("排名:%v 的节点删除成功。。。\n", No)
	}else {
		fmt.Printf("排名:%v 的节点删除失败。。。\n", No)
	}

}
func ShowCircleLinkNode(head *CircleLinkNode) {
	if head.Next == nil {
		fmt.Println("空空如也。。。")
		return
	}
	tmp := head
	for {
		fmt.Printf("排名:%v ,姓名:%v \n", tmp.No, tmp.Name)
		if tmp.Next == head {
			break
		}
		tmp = tmp.Next
	}
	fmt.Println()
}
func main() {
	//初始化环形链表
	head := &CircleLinkNode{}

	head.No = 1

	node01 := &CircleLinkNode{No: 1, Name: "Tom"}
	InsertCircleLinkNode(head, node01)
	node02 := &CircleLinkNode{No: 2, Name: "Jerry"}
	InsertCircleLinkNode(head, node02)
	node03 := &CircleLinkNode{No: 3, Name: "Spike"}
	InsertCircleLinkNode(head, node03)
	fmt.Println("删除前  ===================>")
	ShowCircleLinkNode(head)
	DeleteCircleLinkNode(head, 0)
	fmt.Println("删除0后 ===================>")
	ShowCircleLinkNode(head)
	DeleteCircleLinkNode(head, 1)
	fmt.Println("删除1后 ===================>")
	ShowCircleLinkNode(head)
	DeleteCircleLinkNode(head, 2)
	fmt.Println("删除2后 ===================>")
	ShowCircleLinkNode(head)
	DeleteCircleLinkNode(head, 3)
	fmt.Println("删除 3 后 ===================>")
	ShowCircleLinkNode(head)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值