Joseph 问题:
有 10 个小朋友按编号顺序 1,2,。。。,10 顺时针方向围成一圈。从1号开始顺时针方向 1,2,。。。,9 报数,凡报数 9 者出列(显然,第一个出圈为编号 9 者)
最后一个出圈者的编号是多少?第 5 个出圈者的编号是多少?
实现循环链表
#include "stdlib.h"
#include "stdio.h"
typedef struct LNode{
int data;
struct LNode *next;
} LNode, LinkList;
bool InitList(LinkList* &L) {
// 生成新结点作为头结点,用头指针L 指向头结点
L = new LNode;
// 生成节点失败
if (!L) {
return false;
} else {
// 要实现循环,初始化的时候头结点要指向自己
L->next = L;
L->data = -1;
return true;
}
}
bool RearInsertList(LinkList* &L, LinkList *node){
LinkList *last = NULL;
if(!L || !node){
return false;
}
// 方便往后遍历
last = L;
// 定位到最后一个节点
while(last->next!=L){
last = last->next;
}
// 现在的last是最后一个节点,node插在最后面,指向头结点
node->next = L;
last->next = node;
return true;
}
void DisplayList(LinkList* &L) {
LinkList *p;
if (!L || L == L->next) {
printf("链表为空!\n");
return;
}
p = L->next;
// 是否遍历完
while (p != L) {
printf("%d,", p->data);
p = p->next;
}
}
int main(){
LinkList *L, *s;
int num = 0;
if(InitList(L)){
printf("初始化成功!\n");
} else{
exit(-1);
}
while (num < 10){
s = new LNode;
s->data = num + 1;
s->next = NULL;
if(RearInsertList(L, s)){
printf("%d插入成功\n", num + 1);
} else{
printf("%d插入失败\n", num + 1);
}
num++;
}
DisplayList(L);
return 0;
}
解决约瑟夫问题
#include "stdlib.h"
#include "stdio.h"
typedef struct LNode{
int data;
struct LNode *next;
} LNode, LinkList;
bool InitList(LinkList* &L) {
// 生成新结点作为头结点,用头指针L 指向头结点
L = new LNode;
// 生成节点失败
if (!L) {
return false;
} else {
// 要实现循环,初始化的时候头结点要指向自己
L->next = L;
L->data = -1;
return true;
}
}
bool RearInsertList(LinkList* &L, LinkList *node){
LinkList *last = NULL;
if(!L || !node){
return false;
}
// 方便往后遍历
last = L;
// 定位到最后一个节点
while(last->next!=L){
last = last->next;
}
// 现在的last是最后一个节点,node插在最后面,指向头结点
node->next = L;
last->next = node;
return true;
}
void DisplayList(LinkList* &L) {
LinkList *p;
if (!L || L == L->next) {
printf("链表为空!\n");
return;
}
p = L->next;
// 是否遍历完
while (p != L) {
printf("%d,", p->data);
p = p->next;
}
}
bool Joseph(LinkList* &L, int interval){
LinkList *q, *p = L;
// 报的数,比如第一个人报1,第二个人报2
int i = 0;
int j = 0;
// times表示第几次出局
int times = 0;
if (!L || L == L->next) {
printf("链表为空!\n");
return false;
}
if(interval < 1){
printf("口令不得小于1\n");
return false;
}
do{
i += interval;
//查找第 i 个结点,p 指向该结点的上一个节点
while (p->next){
if(p->next != L){
j++;
}
if(j >= i){
break;
}
p = p->next;
}
times ++;
// 临时保存被删节点的地址
q = p->next;
if(times == 5){
printf("第5个出局的编号:%d\n", times);
}
printf("节点:%d, last:%d, next:%d\n", q->data, p->data, q->next->data);
p->next=q->next;
delete q;
DisplayList(L);
} while (L->next != L);
return true;
}
int main(){
LinkList *L, *s;
int num = 0;
if(InitList(L)){
printf("初始化成功!\n");
} else{
exit(-1);
}
while (num < 10){
s = new LNode;
s->data = num + 1;
s->next = NULL;
if(RearInsertList(L, s)){
printf("%d插入成功\n", num + 1);
} else{
printf("%d插入失败\n", num + 1);
}
num++;
}
DisplayList(L);
printf("\n分割线=============\n");
Joseph(L, 9);
return 0;
}