数据结构与算法——循环链表的算法实现(Joseph 问题)
Joseph 问题:
如果有10 个人,按编号顺序1,2,。。。,10 顺时针方向围成一圈。从1 号开始顺时针方向1,2,。。。,9 报数,凡报数9 者出列(显然,第一个出圈为编号9 者)。
最后一个出圈者的编号是多少?
第5 个出圈者的编号是多少?z
.
代码实现
1 #include<iostream>
2 #include<string>
3 #include<stdlib.h>
4
5 using namespace std;
6
7 typedef struct _LinkNode
8 {
9 int data; //结点的数据域
10 struct _LinkNode* next; //结点的指针域
11 }LinkNode, LinkList; //LinkList 为指向结构体LNode 的指针类型
12
13 void LinkPrint(LinkList* L);
14
15 bool InitList(LinkList*& L) //构造一个空的循环链表L
16 {
17 L = new LinkNode; //生成新结点作为头结点,用头指针L 指向头结点
18 if (!L)return false; //生成结点失败
19 L->next = L; //头结点的指针域指向自己
20 L->data = -1;
21 return true;
22 }
23
24 //尾插法
25 bool ListInsert_back(LinkList*& L, LinkNode* node)
26 {
27 LinkNode* last = NULL;
28 if (!L || !node) return false;
29
30 //找到最后一个节点
31 last = L;
32 while (last->next != L) last = last->next;
33
34 //新的节点链接到最尾部
35 node->next = L;
36 last->next = node;
37
38 return true;
39 }
40
41 bool Joseph(LinkList*& L, int interval)
42 {
43 //在带头结点的循环链表L 中,每个interval 个间隔循环删除节点
44 LinkList* p, * q;
45 int j = 0, i = 0;
46 int times = 0, num = 0;
47 p = L;
48
49 if (!L || p->next == L) {
50 cout << "链表为空!" << endl;
51 return false;
52 }
53
54 if (interval < 1)
55 {
56 cout << "报数淘汰口令不能小于1!" << endl;
57 return false;
58 }
59
60 do
61 {
62 i += interval;
63 while ((p->next)) //查找第i 个结点,p 指向该结点的上一个节点
64 {
65 if (p->next != L) j++;
66 if (j >= i) break;
67 p = p->next;
68 }
69 times++;
70
71 /*if (!(p->next)||(j>i))//当i>n 或i<1 时,删除位置不合理
72 return false;*/
73
74 q = p->next; //临时保存被删结点的地址以备释放空间
75 num = q->data;
76 if (times == 5)cout << "第 5 个出圈的编号是:" << num << endl;
77 printf("cur: %d last: %d next:%d\n", q->data, p->data, q->next->data);
78 p->next = q->next; //改变删除结点前驱结点的指针域
79 delete q; //释放被删除结点的空间
80 LinkPrint(L);
81 } while (L->next != L); //链表不为空,继续报数
82 cout << "最后一个出圈的编号是:" << num << endl;
83
84 return true;
85 }
86
87 void LinkPrint(LinkList* L) //循环链表的输出
88 {
89 LinkList* p;
90 if (!L || L == L->next) {
91 cout << "链表为空!" << endl;
92 return;
93 }
94 p = L->next;
95 while (p != L)
96 {
97 cout << p->data << "\t";
98 p = p->next;
99 }
100 cout << endl;
101 }
102
103 int main()
104 {
105 int i, x;
106 LinkList* L;
107 LinkNode* s;
108
109 //1. 初始化一个空的循环链表
110 if (InitList(L))
111 {
112 cout << "初始化一个空的循环链表!\n";
113 }
114
115 //2. 创建循环链表(尾插法)
116 std::cout << "尾插法创建循环链表, 插入 10 个元素..." << endl;
117 i = 0;
118
119 while ((++i) <= 10)
120 {
121 s = new LinkNode;//生成新结点
122 s->data = i; //输入元素值赋给新结点的数据域
123 s->next = NULL;
124 if (ListInsert_back(L, s)) {
125 cout << "插入成功!" << endl;
126 }
127 else {
128 cout << "插入失败!" << endl;
129 }
130 }
131
132 cout << "尾插法创建循环链表输出结果:\n";
133 LinkPrint(L);
134
135 //3. 解答约瑟夫问题
136 Joseph(L, 9);
137 system("pause");
138 return 0;
139 }
===================================================================================================================
数据结构与算法——循环链表的算法实现(Joseph 问题)的更多相关文章
- 数据结构与算法系列----最小生成树(Prim算法&Kruskal算法)
一:Prim算法 1.概览 普里姆算法(Prim算法).图论中的一种算法.可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中.不但包含了连通图里的全部顶点(英语:Ve ...
- javascript数据结构与算法--高级排序算法
javascript数据结构与算法--高级排序算法 高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法-- ...
- 数据结构C语言版 弗洛伊德算法实现
/* 数据结构C语言版 弗洛伊德算法 P191 编译环境:Dev-C++ 4.9.9.2 */ #include <stdio.h>#include <limits.h> # ...
- 数据结构与算法系列研究七——图、prim算法、dijkstra算法
图.prim算法.dijkstra算法 1. 图的定义 图(Graph)可以简单表示为G=<V, E>,其中V称为顶点(vertex)集合,E称为边(edge)集合.图论中的图(graph ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法)
javascript数据结构与算法--高级排序算法(快速排序法,希尔排序法) 一.快速排序算法 /* * 这个函数首先检查数组的长度是否为0.如果是,那么这个数组就不需要任何排序,函数直接返回. * ...
- 数据结构与算法--最短路径之Bellman算法、SPFA算法
数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...
- javascript数据结构与算法--基本排序算法(冒泡、选择、排序)及效率比较
javascript数据结构与算法--基本排序算法(冒泡.选择.排序)及效率比较 一.数组测试平台. javascript数据结构与算法--基本排序(封装基本数组的操作),封装常规数组操作的函数,比如 ...
- hdu 3336:Count the string(数据结构,串,KMP算法)
Count the string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
随机推荐
- custom-ubuntu-server-iso
Remastering the Ubuntu Desktop ISO is easy considering the existing graphical tools but did you ever ...
- 关于多线程--网络编程 -- 注解反射的一点笔记(JAVA篇)
一 . 线程 java开启一个线程的方法(三种) 方法一:继承Thread类并New一个线程对象 步骤: 1):定义一个类A继承于Java.lang.Thread类. class TestThread ...
- Redis分布式锁的正确使用与实现原理
模拟一个电商里面下单减库存的场景. 1.首先在redis里加入商品库存数量. 2.新建一个Spring Boot项目,在pom里面引入相关的依赖. <dependency> <gro ...
- [C/C++] 结构体内存对齐:alignas alignof pack
简述: alignas(x):指定结构体内某个成员的对齐字节数,指定的对齐字节数不能小于它原本的字节数,且为2^n; #pragma pack(x):指定结构体的对齐方式,只能缩小结构体的对齐数,且为 ...
- php 进行图片裁剪
<?php $src_path = '1.jpg'; //创建源图的实例 $src = imagecreatefromstring(file_get_contents($src_path)); ...
- guitar pro 系列教程(十):关于Guitar Pro声部的使用技巧
作为一个刚接触吉他的萌音乐的玩家,我们在创作吉他谱时一定要注意其中的声部搭配,因为各个声部的配器音色和旋律会对我们的曲子有着非常重要的影响,而声部的把控技术,也可以体现一个音乐人的能力水平的一方面.今 ...
- window安装elasticsearch和kibana
本次测试安装5.1.1版本 es下载地址:https://www.elastic.co/downloads/past-releases/elasticsearch-5-1-1 选择zip kibana ...
- LeetCode周赛#205
5508. 数的平方等于两数乘积的方法数 #模拟 #哈希表 题目链接 题意 给你两个整数数组nums1 和 nums2 ,请你返回根据以下规则形成的三元组的数目(类型 1 和类型 2 ): 类型 1: ...
- JQuery案例:购物车编辑
购物车编辑 实现了:商品的加减,总价的变动 实现了:全选/全不选(使用prop而不是attr) 实现了:删除(遮罩层) <html> <head> <meta chars ...
- Java基础教程——继承
继承 一个类 可以 继承自 另一个类: 派生的类(子类)继承父类的方法和数据成员: 关键字:子类 extends 父类. public class 继承 { public static void ma ...