#define Error -1
#define OK 1
typedef int Status;
typedef int ElementType;
typedef struct Node{
ElementType data;
struct Node * next;
}Node, * LinkList;
//循环链表 获得第i个元素的值
Status GetCycleElement(LinkList L, int i, ElementType *e){
if (i < 1) {
return errno;
}
Node *node = L;
for (int j = 0; j < i; j++) {
node = node->next;
if (!node || node == L) {
return errno;
}
}
*e = node->data;
return OK;
}
//循环链表 插入一个元素
Status CycleListInsert(LinkList L, int i , ElementType e){
int length = cycleListGetLenth(L);
if (i < 1 || i > length + 1) {
return errno;
}
Node *node = L;
for (int j = 1; j < i; j++) {
node = node->next;
}
Node *inserNode = (Node *)malloc(sizeof(Node));
inserNode->data = e;
inserNode->next = node->next;
node->next = inserNode;
return OK;
}
// //循环链表 得到链表的长度
int cycleListGetLenth(LinkList L){
Node *node = L;
if (L->next == L) {
return 0;
}
int length = 0;
while (node->next != L) {
node = node->next;
length++;
}
return length;
}
//循环链表 删除节点(获得该节点的前一个节点的值)
LinkList CyclelistDeleteElement(LinkList L, Node *deleteNode){
int length = cycleListGetLenth(L);
Node *tempNode = L;
for (int i = 0 ; i < length; i++) {
if (tempNode->next == deleteNode) {
break;
}
tempNode = tempNode->next;
}
tempNode->next = deleteNode->next;
free(deleteNode);
return tempNode;
}
//循环链表 创建单链表
LinkList CreateCycleListTail(LinkList * p){
Node *headNode = (Node *)malloc(sizeof(Node));
headNode->next = headNode;
headNode->data = 1111;
*p = headNode;
return headNode;
}
//循环链表 打印节点
void LogCycleListNode(LinkList p){
int length = cycleListGetLenth(p);
Node *node = p;
for (int i = 0; i < length; i++) {
node = node->next;
printf("--%d--", node->data);
}
printf("--- \n");
}
// 约瑟夫问题
//据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏
// L 链表(带有头结点)
// length 总共几个人
// n 第几个死亡
void JosephusProblem(LinkList p , int length, int n){
for (int i = 1; i <= length; i++) {
CycleListInsert(p, i, i);
}
int j = 0;
int k = length;
Node *tempNode = p;
while (k) {
j++;
tempNode = tempNode->next;
//如果是头指针,指向下一个
if (tempNode == p) {
tempNode = tempNode->next;
}
if (j == n) {
printf(" %d", tempNode->data);
// 删除节点,并将节点指向被删除的节点的前一个节点
tempNode = CyclelistDeleteElement(p, tempNode);
k--;
j = 0;
}
}
}
//魔术师发牌问题 假设13张牌 10966+1180
void magigian(LinkList L, int n){
for (int i = 1; i <= n ; i++) {
CycleListInsert(L, i, 0);
}
Node *tempNode = L;
for (int i = 1; i <= n; i++) {
for (int j = 0; j < i; j++) {
tempNode = tempNode->next;
//如果节点指向头节点或者 该节点已经有值,则这次不算, 让j减少1
if (tempNode == L || tempNode->data != 0) {
j--;
}
}
tempNode->data = i;
}
// --1----8----2----5----10----3----12----11----9----4----7----6----13-----
LogCycleListNode(L);
}
线性表的循环链表
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 题目一:判断单链表中是否有环 描述:1.有环的定义:链表的尾结点指向了链表中的某个结点 两种解决方案 【方法一】 ...
- 场景描述:魔术师利用一副牌中的13张黑牌,预先将他们排好叠放在一起,牌面朝下。对观众说“我不看牌,只数数就可以猜测...
- 循环链表 对于单链表,由于每个结点只存储了向后的指针,到了尾部标识就停止了向后链的操作。也就是说,按照这样的方式,...