数据结构篇——循环链表

判断单链表中是否有环:
 

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;
}Node,circlelinklist;
Node *R;

void init(circlelinklist *L){
	L->data=0;
	L->next=L;
	R=L;
	Node *C;  // 循环点
	for(int i=1;i<=10;i++){
        Node *n=malloc(sizeof(Node));
        if(i==5){
        	C=n;
        }
        n->data=i;
        n->next=R->next;
        R->next=n;
        R=n;
	}
	R->next=C;
}
void show(circlelinklist *L){
    Node *p=L;
    printf("[");
    while(1){
    	p=p->next;
    	if(p==R){
    		printf("%d]\n",p->data);
    		break;
    	}else{
    		printf("%d",p->data);
    	}
    }
}
void hasloopA(circlelinklist *L){
	Node *A=L;
	Node *B=L;
	while(A->next!=B->next->next){
		A=A->next;
		B=B->next->next;
	}
	printf("有环!\n");
}
void hasloopB(circlelinklist *L){
    Node *A=L;
    Node *B=L;
    int count=0;
    while(1){
         A=A->next;
         cunt++;
         B=L;
         for(int i=0;i<count;i++){
             B=B->next;
             if(A->data==B->data&&count!=i){
                 printf("有环!%d\n",A->data);
             	 return;
             }
         }
    }
}
void main(){
	circlelinklist L;
	init(&L);
	show(&L);
	// hasloopA(&L);
	hasloopA(&L);
    hasloopB(&L);
}

约瑟夫环问题(1)

据说著名犹太历史学家Josephus有过一下的故事: 在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的一个朋友躲到一个洞中,39个犹太人决定宁 愿死也不要被敌人抓到,于是决定一个自杀方式,41个人排成一个圆圈,有第1个人开始报数,每报数到第3 个人该人就必须自杀,然后由下一个人重新开始报数,直到所有人都自杀身亡为止。 然而Josephus和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16 个与第31个位置,于是逃过了这场死亡游戏。

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;
}Node,circlelinklist;

void init(circlelinklist *L){
	L->next=L;
	L->data=0;
	Node *R=L;
	for(int i=1;i<=41;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;
		R->next=n;
		R=n;
		L->data++;
    }
	R->next=L->next;
}	
void josephus(circlelinklist *L){
	Node *p=L;
    int count=0;
    while(L->data>0){
        p=p->next;
        count++;
        if(count==2){
            Node *n=p->next;
            p->next=n->next;
            printf("%d",n->data);
            free(n);
            L->data--;
            count=0;
        }
	}
}
void main(){
	circlelinklist L;
	init(&L);
	josephus(&L);
}

约瑟夫环问题(2)

编号为1~N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),开始人选一个正整数作为 报数上限值M,从第一个人按顺时针方向自1开始顺序报数,报道M时停止报数。报M的人出列,将他的密 码作为新的M值,从他顺时针方向上的下一个人开始从1报数,如此下去,直至所有人全部出列为止。 (10 个人 {3,6,5,4,6,3,5,8,9,4}

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
typedef struct Node{
	ElemType data;
	int position;
	struct Node *next;
}Node,circlelinklist;
Node *R;
void init(circlelinklist *L){
    int pass[]={3,6,5,4,6,3,5,8,9,4};
    L->data=0;
    L->next=L;
    R=L;
    for(int i=0;i<10;i++){
    	Node *n=malloc(sizeof(Node));
    	n->data=pass[i];
    	n->position=i+1;
    	n->next=R->next;
    	R->next=n;
    	R=n;
    	L->data++;
    }
    R->next=L->next;
}
void startGame(circlelinklist *L){
    Node *p=L;
    int M;
    while(L->data>0){
        M=p->next->data;
        for(int i=0;i<M-1;i++){
            p=p->next;
        }
        Node *n=p->next;
        p->next=n->next;
        M=n->data;
        printf("%d号出列\n",n->position);
        free(n);
        L->data--;
    }
}
void main(){
	circlelinklist L;
	init(&L);
	srartGame(&L);
}

约瑟夫环问题(3)

逢七过,不用解释了吧。8个人100以内

#include<stdio.h>
#incllude<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int Boolean;
typedef int ElemType;
type struct Node{
	ElemType position;
    struct Node *next;
}Node,circlelinklist;
Node *R;

void init(circlelinklist *L){
	L->data=0;
	L->next=L;
	R=L;
	for(int i=1;i<=8;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;
		R->next=n;
		R=n;
		L->data++;
	}
	R->next=L->next;
}
Boolean isContaionSeven(int num){
	// 12%10~2 1  712%10 2 71%10 1 
    while(num!=0){
    	if(num%10==7){
    		return TRUE;
    	}else{
    		num=num/10;
    	}
    }
    return FALSE;
}
void fengsevenguo(circlelinklist *L){
	Node *p=L;
	for(int i=1;i<=100;i++){
		p=p->next;
		if(p->data==4){ //取4号位应该说过的数字
	        if(i%7==0||isContaionSeven(i)){
            printf("%d号位:%d\n",p->data,i);
		    }
		
		}
	}
}
void main(){
	circlelinklist L;
	init(&L);
	fengsevenguo(&L);
}

数字集  人集

#include<stdio.h>
#incllude<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int Boolean;
typedef int ElemType;
typedef int position;

typedef struct LNode{ //数字集 单列表
	ElemType data;
	struct LNode *next;
}LNode,NumList;

typedef struct Person{
	ElemType data; //人的位置
	NumList list; // 人的数字集
    struct Person *next;
}Person,PersonList;

Person *R; //人的循环列表的尾指针

void insert(NumList *L,int num){
	LNode *n=malloc(sizeof(LNode));
	n->data=num;
	n->next=L->next;
	L->next=n;
	L->data++;
}

void initList(NumList *L){
    L->data=0;
    L->next=NULL;
}
void init(PersonList *p){
    p->position=0;
    p->next=p;
    R=p;
    for(int i=1;i<=8;i++){
    	Person *n=malloc(sizeof(Person));
    	n->data=i; //位置
    	initList(&(*n)n->list);
        n->next=R->next;
    	R->next=n;
    	R=n;
    	p->data++;
    }
    R->next=p->next;
}
Boolean isContaionSeven(int num){
	// 12%10~2 1  712%10 2 71%10 1 
    while(num!=0){
    	if(num%10==7){
    		return TRUE;
    	}else{
    		num=num/10;
    	}
    }
    return FALSE;
}
void fengsevenguo(PersonList *p){
	Person *p=p;
	for(int i=1;i<=100;i++){
		p=p->next;
		if(i%7==0||isContaionSeven(i)){
			insert(p->list,i);
		}
	}
}
void showList(NumList *L){
	LNode *n=L;
	for(int i=0li<L->data;i++){
        if(i=L->data-1){
        	printf("%d]\n",n->data);
        }else{
        	printf("%d",n->data);
        }
	}
}
void show(PersonList *p){
    Person *p=p;
    for(int i=0;i<p->data;i++){
    	p=p->next;
    	printf("%d号玩家:",p->data);
    	showList(p->list);
    }
}
void main(){
	PersonList p;
	init(&p);
	fengsevenguo(&p);
	show(&p);
}

魔术师发牌问题

魔术师利用一副牌中的13张黑牌,预先将他们拍好后叠放在一起,牌面朝下。对观众说:“我不看牌, 只数数就可以猜到每张牌是什么,我大声数数,你们听,不信?现场演示。”魔术师将最上面的那张牌数为 1,把他翻过来正好是黑桃A,将黑桃A放在桌子上,第二次数1,2,将第一张牌放在这些牌的下面,将第二 张牌翻过来,正好是黑桃2,也将它放在桌子上,这样依次进行将13张牌全部翻出,准确无误。那么,牌的 开始顺序如何安排的?

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1 //已经被·赋值
#define FALSE 0  //没有赋值
typedef int ElemType;
typedef int Status;
typedef struct Node{
	ElemType data;
	int flag;   //标记 在初始化时使用
	struct Node *next;
}Node,circlelinklist;
Node *R;

void init(circlelinklist *L){
	L->data=0;
	L->next=L;
	R=L;
	for(int i=1;i<=13;i++){
		Node *n=malloc(sizeof(Node));
		n->data=0;
		n->flag=FALSE;
		n->next=R->next;
		R->next=n;
		R=n;
		L->data++;
	}
	R->next=L->next;
	Node *p=L;
	// 对13张牌进行赋值
	for(int i=1;i<=L->data;i++){
		int count=0;
		while(count<i){
            p=p->next;
            if(p->flag==TRUE){
            	continue;
            }
            count++;
            if(count==i){
            	p->data=i;
            	p->flag=TRUE;

            }
		}
	}
}
void show(circlelinklist *L){
	Node *p=L;
	printf("[");
	while(1){
		p=p->next;
		if(p=R){
            printf("%d]\n",p->data);
            break;
		}else{
			printf("%d",p->data);
		}
	}
}
void play(circlelinklist *L){
	Node *p=R;
	Node *pre=R;
	int num=1; // 初来的那张牌  2 3
	int count=0;
	while(L->data>0){
		while(count<num){
			pre=p;
            p=p->next;
            count++;
            if(count==num){
                Node *n=p;
                pre->next=n->next;
                printf("%d\n",n->next);
                p=pre;
                free(n);
                L->data--;
            }
		}
		count=0;
		num++;
	}
}
void main(){
	circlelinklist L;
	init(&L);
	show(&L);
	play(&L);

}

拉丁方阵问题

拉丁方阵是一种n×n的方阵,方阵中恰有n种不同的元素,每种元素恰有n个,并且每种元素在一行一列 中恰好出现一次

#include<stdio.h>
#include<stdlib.h>

typedef int ElemType;
type struct Node{
	ElemType data;
	struct Node *next;
}Node,circlelinklist;
Node *R;

void init(circlelinklist *L){
	L->data=0;
	L->next=L;
	for(i=1;i<=9;i++){
		Node *n=malloc(sizeof(Node));
		n->data=i;
		n->next=R->next;
		R=n;
		L->data++;
	}
	R->next=L->next;
}
void show(circlelinklist *L){
	NOde *p=R;
	for(int i=1;i<=L->data;i++){
		p=p->next; //当i=1 从第一个元素开始
		n=p;
		while(1){
			printf("%d",n->data);
			n=n->next;
			if(n==p){
				break;
			}
		}
		printf("\n");
	}
}
void main(){
	circlelinklist L;
	init(&L);
	show(&L);
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值