约瑟夫环问题--非链表解法

一、问题描述

    n个数字,[0,n-1],连成环,从第1个数开始,找到第m个数,删除,然后从删除后的下一个数开始继续数第m个数删除,问最后剩下哪个数

二、解法

    1、通过设定状态标志位,(声明一个状态数组status[N],status[i]==0时表示未出圈,出圈时将对应第i号人的status置为出圈的次数;即status[i]=count)
    2、循环条件是:当count值在N范围内,则循环;

    3、最后剩下的数就是status数组状态值仍为0的下标对应的数。

三、C代码

/*******************************************************
Author:tmw
date:2018-3-17
********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int joseph( int* array, int array_len, int m )
{
    int count = 0;  //用于记录删除了多少个元素
    int start = -1;  //初始值若为0,则需要单独对第0个位置的元素计数,设为-1就囊括在死循环里了

    /**状态标记数组,如果为0表示未被删除,非0表示已被删除**/
    int status[array_len];
    memset(status,0,sizeof(status));

    while( count<array_len-1 )
    {
        int i = 0;

        while(1)
        {
            /**从标记数组的下一位开始计数**/
            start = (start+1)%array_len;
            if( status[start] == 0 )
                i++;

            /**
                当数到第m个数时,array[i]出列---即:该位置状态值非0,
                且出列count++,并且跳出循环,重新再从0数到m
            **/
            if( i == m )
            {
                count++;
                status[start] = count;
                break;
            }
        }
    }

    /**找到状态值为0的下标,并返回对应的值**/
    int k = 0;
    while( k<array_len )
    {
        if( status[k] == 0 )
            break;
        k++;
    }

    printf("最后剩下的元素位置为:%d  值为:%d\n",k,array[k]);

//    int i;
//    for( i=0; i<array_len; i++ )
//        printf("%d ",status[i]);
//    printf("\n");

    return array[k];
}

四、测试代码及结果

int main()
{
    printf("测试代码\n");
    int array1[10] = {1,2,3,4,5,6,7,8,9,10};
    joseph(array1,10,4);

    int array2[20] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
    joseph(array2,20,2);

    return 0;
}


猜你喜欢

转载自blog.csdn.net/qiki_tangmingwei/article/details/80109491