狐狸逮兔子——链式存储方式

问题描述

围绕着山顶有n个圆形排列的洞,狐狸要吃兔子,兔子说:”可以,但必须找到我,我就藏于这n个洞中,你先到1号洞找,第二次隔1个洞(即3号洞)找,第二次隔2个洞(即6号洞)找,以后如此类推,次数不限.”但狐狸从早到晚进进出出了m次,仍没有找到兔子.问:兔子究竟藏在那个洞里?

 

问题分析

这实际上是一个反复查找循环链表的过程.

定义一个循环链表,用户自己输入洞的个数n和查找次数m,用具有n个元素的循环链表来表示这n个洞.每个元素表示围绕山顶的一个洞,下标为洞的编号.对所有洞设置初始标志为0,然后通过m次循环,对每次所进之洞修改标志为1,最后输出标志为0的洞,即兔子藏身的洞.

 

解决问题

typedef int Status;
typedef int ElemType;                            //结构体里洞的编号和标志为整型
typedef struct LNode
{
	ElemType data;		//洞的编号
	ElemType flag;		//洞的标志,1表示狐狸进过此洞,0表示狐狸没有进过此洞
	struct LNode *next;
}*LinkList,LNode;

构造一个循环链表,并给n个洞编号,设置洞的初始标志为0.

LinkList InitList(int n)
{//构造一个循环链表L
	int i;
	LinkList p,L;
 	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL;
	p=L;
	for(i=1;i<=n;i++)
	{
		p->data=i;
		p->flag=0;
		if(i!=n)
		{
			p->next=(LinkList)malloc(sizeof(LNode));
			p=p->next;
		}
		if(i==n)
		{
			p->next=L;
		}
	}
	return L;
}

遍历链表,分别输出洞的编号和标志. 

Status traverselist(LinkList L,int n)
{//遍历链表
    LinkList p;
    p=L;
    int i;
    printf("洞的编号:");
    for(i=0;i<n;i++)
    {
        printf("%3d",p->data);
        p=p->next;
    }
    printf("\n");
    printf("洞的标志:");
    for(i=0;i<n;i++)
    {
        printf("%3d",p->flag);
        p=p->next;
    }
    printf("\n");
    return OK;
}

狐狸开始找兔子,将进入过的洞标志改为1,寻找m次结束 。最后输出标志仍为0的洞,即兔子可能藏身地点。

Status Search(LinkList L,int m,int n)
{
    int i,j;
    LinkList p;
    p->flag=1;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=i+1;j++)
        {
            p=p->next;
        }
        p->flag=1;

    }
    printf("兔子可能存在的位置为:");
    p=L;
    for(i=0;i<n;i++)
    {
        if(p->flag==0)
        {
            printf("%3d",p->data);
        }
        p=p->next;
    }
    printf("\n\n");
    return OK;
}

 

全部代码

#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef int Status;
typedef int ElemType;
typedef struct LNode
{
	ElemType data;		//洞的编号
	ElemType flag;		//洞的标志,1表示狐狸进过此洞,0表示狐狸没有进过此洞
	struct LNode *next;
}*LinkList,LNode;

LinkList InitList(int n)
{//构造一个循环链表L
	int i;
	LinkList p,L;
 	L=(LinkList)malloc(sizeof(LNode));
	L->next=NULL;
	p=L;
	for(i=1;i<=n;i++)
	{
		p->data=i;
		p->flag=0;
		if(i!=n)
		{
			p->next=(LinkList)malloc(sizeof(LNode));
			p=p->next;
		}
		if(i==n)
		{
			p->next=L;
		}
	}
	return L;
}

Status traverselist(LinkList L,int n)
{//遍历链表
    LinkList p;
    p=L;
    int i;
    printf("洞的编号:");
    for(i=0;i<n;i++)
    {
        printf("%3d",p->data);
        p=p->next;
    }
    printf("\n");
    printf("洞的标志:");
    for(i=0;i<n;i++)
    {
        printf("%3d",p->flag);
        p=p->next;
    }
    printf("\n");
    return OK;
}

Status Search(LinkList L,int m,int n)
{
    int i,j;
    LinkList p;
    p->flag=1;
    for(i=1;i<=m;i++)
    {
        for(j=1;j<=i+1;j++)
        {
            p=p->next;
        }
        p->flag=1;

    }
    printf("兔子可能存在的位置为:");
    p=L;
    for(i=0;i<n;i++)
    {
        if(p->flag==0)
        {
            printf("%3d",p->data);
        }
        p=p->next;
    }
    printf("\n\n");
    return OK;
}

int main()
{
    int m,n;
    printf("请输入查找次数和洞的个数;");
    scanf("%d%d",&m,&n);
    printf("\n");
	LinkList L;
	L=InitList(n);
	printf("初始:\n\n");
	traverselist(L,n);
	printf("\n******************************************\n\n");
	Search(L,m,n);
	printf("寻找%d次,结果为:\n\n",m);
	traverselist(L,n);
	return 0;
}

 

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值