算法----约瑟夫环的简易实现
2014-07-10 12:20
281 查看
题目:用户输入M,N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出。
分析:该题目的通用解法是利用循环链表,当然也可以利用循环数组。易于扩展的做法是,定义循环链表的数据结构,并实现循环链表的基本操作,利用这些基本操作如插入、删除、初始化、构建链表等操作;简易的实现方法则是仅适合该题目的解法。
采用无头的循环链表,如果有头,则需要在每次遍历中跳过头节点。因为采用了无头的链表,因此在插入或者删除时,需要针对头节点特殊处理:
1、插入时,链表为空,则当前待插入的节点为链表头;
2、删除时,由于题目只要求输出删除节点,链表又是循环链表,因此可以不考虑删除节点为头节点的情况。不过,为了删除当前节点,我们需要保存其前驱结点的指针。
代码如下:
#include <iostream>
#include "joseph.h"
using namespace std;
void joseph()
{
int m = 0, n = 0;
cin >> n >> m;
Node head = NULL;
Node current = NULL;
for (int i = 1; i <= n; ++i) {
Node tempNode = new ListNode();
tempNode->data = i;
if (head == NULL) { //构建链表,特殊处理头节点
head = tempNode;
head->next = head;
current = head;
} else {
current->next = tempNode;
tempNode->next = head;
current = current->next;
}
}
Node prev = current; //此处有些取巧,我们从链表头开始遍历链表,其前驱应为表尾,链表构建完成过后current指针恰好为表尾,因此先保存该指针
current = head; //再给current赋值,指向表头
int cnt = 1; //初始化计数器,当前节点计数器为1
while (current != current->next) { //循环条件为直至链表剩余一个元素,此时current != current->next
if (cnt == m) {
cnt = 1; //当前节点需要删除,重置计数器
prev->next = current->next; //更改当前节点的前驱结点的后继结点为当前节点的后继
cout << current->data << '\t';
delete current;
current = prev->next; //重新赋值current
} else {
++cnt;
prev = current;
current = current->next;
}
}
cout << current->data << endl; //输出链表最后一个元素
delete current;
}
分析:该题目的通用解法是利用循环链表,当然也可以利用循环数组。易于扩展的做法是,定义循环链表的数据结构,并实现循环链表的基本操作,利用这些基本操作如插入、删除、初始化、构建链表等操作;简易的实现方法则是仅适合该题目的解法。
采用无头的循环链表,如果有头,则需要在每次遍历中跳过头节点。因为采用了无头的链表,因此在插入或者删除时,需要针对头节点特殊处理:
1、插入时,链表为空,则当前待插入的节点为链表头;
2、删除时,由于题目只要求输出删除节点,链表又是循环链表,因此可以不考虑删除节点为头节点的情况。不过,为了删除当前节点,我们需要保存其前驱结点的指针。
代码如下:
#include <iostream>
#include "joseph.h"
using namespace std;
void joseph()
{
int m = 0, n = 0;
cin >> n >> m;
Node head = NULL;
Node current = NULL;
for (int i = 1; i <= n; ++i) {
Node tempNode = new ListNode();
tempNode->data = i;
if (head == NULL) { //构建链表,特殊处理头节点
head = tempNode;
head->next = head;
current = head;
} else {
current->next = tempNode;
tempNode->next = head;
current = current->next;
}
}
Node prev = current; //此处有些取巧,我们从链表头开始遍历链表,其前驱应为表尾,链表构建完成过后current指针恰好为表尾,因此先保存该指针
current = head; //再给current赋值,指向表头
int cnt = 1; //初始化计数器,当前节点计数器为1
while (current != current->next) { //循环条件为直至链表剩余一个元素,此时current != current->next
if (cnt == m) {
cnt = 1; //当前节点需要删除,重置计数器
prev->next = current->next; //更改当前节点的前驱结点的后继结点为当前节点的后继
cout << current->data << '\t';
delete current;
current = prev->next; //重新赋值current
} else {
++cnt;
prev = current;
current = current->next;
}
}
cout << current->data << endl; //输出链表最后一个元素
delete current;
}
相关文章推荐
- C语言算法实现约瑟夫环2
- shuffle算法的一种简易实现
- 五子棋AI算法简易实现(五)
- 小算法:约瑟夫环的Java实现
- 五子棋AI算法简易实现(二)
- 五子棋AI算法简易实现(一)
- 实现约瑟夫环的算法
- Spark-Mllib中各分类算法的java实现(简易教程)
- merge_sort相比算法导论简易版本实现
- 五子棋AI算法简易实现(三)
- 简易 bokeh 图像散景效果算法实现
- 二叉查找树——算法导论第12章简易代码实现~
- 约瑟夫环及其变种算法 java实现
- 【算法】C语言实现简易的扑克牌游戏
- 自己实现的简易的knn算法
- 实现简易字符串压缩算法:由字母a-z或者A-Z组成,将其中连续出现2次以上(含2次)的字母转换为字母和出现次数,
- 五子棋AI算法简易实现(六)
- 实现简易字符串压缩算法:一个长度最大为128的字符串, 由字母a-z或者A-Z组成,将其中连续出现2次以上(含2次)的字母转换为字母和出现次数,以达到压缩目的
- 约瑟夫环实现算法
- C语言算法实现约瑟夫环1