开发者学堂课程【Go 语言核心编程 - 数据结构和算法: 数据结构和算法-约瑟夫问题解决(1)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9846
数据结构和算法-约瑟夫问题解决(1)
本节主要讲解,如何用代码实现约瑟夫问题解决:
1. 走代码:
打开 Visual Stdio Code,新建文件夹。
示意图中每一个圆圈就代表一个小孩,就应该用一个结构体描述这个小孩,直接写主函数。
首先写一个函数,把单向链表完成,创建小孩的结构体。
package main
Import (
"fmt"
)
//小孩的结构体
type Boy struct{
No int//编号(出圈的顺序)
Next *Boy//指向下一个小孩的指针[默认值是 nil]
//编写一个函数,构成单向的环形链表
最好构建变量
//num:表示小孩的个数
//*Boy;返回该环形的链表的第一个小孩的指针(从哪走都需要第一个小孩的定位,如果没有第一个小孩代码是走不下去的)
func AddBoy(num int)*Boy{
First :=&Boy{}//空结点
curBoy :=&Boy{}//空结点
//判断
If num<1 //如果一个人都没有,就不能构建环形链表
Fmt.println(“num 的值不对”)
Return first
}
//循环的构建这个环形链表
For i:=1;i<=num;i++{
先创建小孩,用循环的方式赋值i
Boy:=&boy{
No :i,
//分析构成循环链表,需要一个辅助指针[ 帮忙 ] 需要帮忙的原因是 first 指针一旦给了就不能动
//1.因为第一个小孩比较特殊,需要两个逻辑来处理
If i==1{//第一个小孩
First = boy
指完之后头指针就不能动了,应该有一个辅助指针来帮助形成循环链表
curBoy = Boy
curBoy.Next=first
//形成一个循环,自己指向自己
}else{
curBoy.Next=boy
curBoy = Boy
curBoy.Next=first//构成环形链表
}
}
Return first
}
//显示单向环形链表[遍历]
Func ShowBoy(first *Boy){
要显示一堆小孩,必须先看 first 指 针,遍历时候一般也不动 first 指针。
//处理一下环形链表为空
If first.next=nil{
Fmt.println(“链表为空,没有小孩...’’)
Return
//创建一个指针,帮助遍历[说明至少有一个小孩]
curBoy;=first
For{
Fmt.printf(“小孩编号=%d ->”,curBoy.No)
先输出小孩儿信息
//退出的条件?否则就会死在里边
先输出,再判断,输出1之后再判断2
If cutboy.next==nil{
显示到最后一个小孩
break
}
}
}
func main(){
First:=AddBoy(5)
//调用
//显示
showBoy(first)
}
没有报错
2. 示意图:
假设只有一个小孩,就让 first 指向它,curBoy 也指向它,相当于两个指针一起指向它,接下来让 curBoy.Next 指向 first,相当于它里边有一个 next 指针,就是它自己指向自己,自己形成一个环形的,第一个小孩就这样处理。来了2号小孩,很显然它不是环形链表那就让它移到2号小孩,然乎重新让2号指向1号,就形成了环形链表。