**
数据结构之循环链表
**
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
/*
有 10 个小朋友按编号顺序 1,2,。。。,10 顺时针方向围成一圈。
从 1 号开 始顺时针方向 1,2,。。。,9 报数,凡报数 9 者出列
(显然,第一个出圈为 编号 9 者)。 最后一个出圈者的编号是多少?
第 5 个出圈者的编号是多少?
*/
typedef struct _LinkNode {
int data; //结点的数据域
struct _LinkNode* next; //结点的指针域
}LinkNode,LinkList; //LinkList 为指向结构体 LNode 的指针类型
void LinkPrint(LinkList* L);
bool InitList(LinkList* & L) {//构造一个空的循环链表 L
L = new LinkNode; //生成新结点作为头结点,用头指针 L 指向头结点
if (!L) return false; //生成结点失败
L->next = L;//头结点的指针域指向自己
L->data = -1;
return true;
}
//尾插法
bool ListInsert_back(LinkList*& L, LinkNode* node) {
LinkNode* last = NULL;
if (!L || !node) return false;
//找到最后一个结点
last = L;
while (last->next != L) last = last->next;
//新的节点链接到最尾部
node->next = L;
last->next = node;
return true;
}
//删除节点
bool Joseph(LinkList*& L, int interval) {
//在带头节点的循环链表L中,每个interval个间隔循环删除节点
LinkList* p, * q;
int j = 0;
int i = 0;
int times = 0, num = 0;
p = L;
if (!L || p->next == L) {
cout << "链表为空" << endl;
return false;
}
if (interval < 1) {
cout << "报数淘汰的口令不能小于1!" << endl;
return false;
}
do {
i += interval;
while ((p->next)) { //查找第 i 个结点,p 指向该结点的上一个节点
if (p->next != L) j++;
if (j >= i) break;
p = p->next;
}
times++; //圈数加一
/*if (!(p->next)||(j>i))//当 i>n 或 i<1 时,
删除位置不合理 return false;*/
q = p->next; //临时保存被删节点的地址以备释放空间
num = q->data;
if (times == 5) cout << "第 5 个出圈的编号是:" << num << endl;
printf("cur: %d last: %d next:%d\n", q->data, p->data, q->next->data);
p->next = q->next; //改变删除结点前驱结点的指针域
delete q; //释放被删节点的空间
LinkPrint(L); //打印出剩下节点的表中的各值
} while (L->next != L); //链表不为空,可以继续报数
cout << "最后一个出圈的编号是:" << num << endl;
return true;
}
//循环链表的输出
void LinkPrint(LinkList* L) {
LinkList* p;
if (!L || L == L->next) {
cout << "链表为空" << endl;
return;
}
p = L->next;
while (p!= L) {
cout << p->data << "\t";
p = p->next;
}
cout << endl;
}
int main(void) {
int i, x;
LinkList* L;
LinkNode* s;
//1.初始化一个空的循环链表
if (InitList(L)) {
cout << "初始化一个空的循环链表!\n";
}
//2.创建循环链表(尾插法)
cout << "尾插法创建循环链表,插入10个元素..." << endl;
i = 0;
while ((++i) <= 10)
{
s = new LinkNode; //生成新的节点
s->data = i; //输入元素值赋给新节点的数据域
s->next = NULL;
if (ListInsert_back(L, s)) {
cout << "插入成功" << endl;
}
else {
cout << "插入失败" << endl;
}
}
cout << "尾插法创建循环链表输出结果:\n";
LinkPrint(L);
//3.解答约瑟夫问题
Joseph(L, 9);
system("pause");
return 0;
}
运行结果如下: