经典循环链表之约瑟夫问题:标号从1到n的n个人围成一个圈,从1开始计数到m的人退出圈子,然后从退出的下一个人开始接着从1计数,数到m的人后继续退出,最后只剩下一个人,求剩下人的编号。这便是约瑟夫问题的模型。
经典循环链表之魔术师发牌问题:魔术师手中有A、2、3……J、Q、K十三张黑桃扑克牌。在表演魔术前,魔术师已经将他们按照一定的顺序叠放好(有花色的一面朝下)。魔术表演过程为:一开始,魔术师数1,然后把最上面的那张牌翻过来,是黑桃A;然后将其放到桌面上;第二次,魔术师数1、2;将第一张牌放到这些牌的最下面,将第二张牌翻转过来,正好是黑桃2;第三次,魔术师数1、2、3;将第1、2张牌依次放到这些牌的最下面,将第三张牌翻过来正好是黑桃3;……直到将所有的牌都翻出来为止。问原来牌的顺序是如何的。
链表相交:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//定义单向循环链表结点
typedef struct cNode{
int data;
struct cNode* next;
}cnode;
cnode* create_cNode(const int length){
cnode* head = (cnode*)malloc(sizeof(cnode));
cnode* p = head;
for(int i=0;i<length;i++){
p->next = (cnode*)malloc(sizeof(cnode));
p->next->data = i+1;
p=p->next;
}
p->next = head->next;
return head;
}
//打印所有结点
void print_cNode(cnode* cNode){
cnode* p = cNode->next;
while(p->next!=cNode->next){
printf("%d\n",p->data);
p=p->next;
}
printf("%d\n",p->data);
}
//判断一个链表是否带环
//思路:设置一个快指针一次走2步,一个慢指针一次走1步,如果快指针与慢指针相遇则带环
int with_loop_or_not(cnode* cNode){
if(cNode==NULL){
return 0;
}
cnode* fast = cNode->next;
cnode* slow = cNode;
while(fast!=slow && fast->next!=NULL&&fast->next->next!=NULL){
fast = fast->next->next;
slow = slow->next;
}
if(fast==slow){
return 1;
}
else{
return 0;
}
}
//寻找带环链表的入口
//思路: 对于带环链表,从求出的相遇点挨个向下走,
//另一个指针从头结点挨个向下走,两个指针相遇的地方就是环入口
cnode* loop_enter(cnode* cNode){
//先求出快慢指针在环内的相遇点
if(cNode==NULL){
return 0;
}
cnode* fast = cNode->next;
cnode* slow = cNode;
while(fast!=slow && fast->next!=NULL&&fast->next->next!=NULL){
fast = fast->next->next;
slow = slow->next;
}
//求入口
cnode* step = cNode;
cnode* loop_step = fast;
while(step!=loop_step){
step=step->next;
loop_step=loop_step->next;
}
return step; //入口点
}
//判断链表是否相交
//相交的意思是两个链表的尾部若干个结点是重合的。
//方法一:分别求两个链表的尾指针, 若两个尾指针相等则相交。
//方法二:把其中一个链表的首尾相连,在此基础上,若第二个链表存在环,则两个链表相交
//约瑟夫问题
void ysf(cnode* cNode,int n, int m){
cnode* p=cNode;
while(p->next!=p){
int k = 1;
while(k!=m){
p=p->next;
k+=1;
}
cnode* s = p->next;
p->next = s->next;
free(s);
}
printf("%d\n",p->data);
}
//魔术师发牌问题
cnode* mss(int length){
cnode* head = (cnode*)malloc(sizeof(cnode));
cnode* p = head;
for(int i=0;i<length;i++){
p->next = (cnode*)malloc(sizeof(cnode));
p->next->data = 0;
p=p->next;
}
p->next = head->next;
p = head->next;
p->data = 1;
for(int num = 2;num<=13;num++){
int i = 0;
while(i<num){
p = p->next;
if(p->data==0){
i++;
}
}
p->data = num;
}
return head;
}
void main(){
//cnode* cNode = create_cNode(41);
cnode* mms_ = mss(13);
print_cNode(mms_);
//ysf(cNode,41,3);
return ;
}