查找有序序列中 重复/不存在 的数算法

/*
 * 查找有序序列中 重复/不存在 的数算法演示
 * 版权所有:http://www.cppblog.com/converse/
 */

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

#define FUNC_IN()   printf("\nin  %s\n\n", __FUNCTION__)
#define FUNC_OUT()  printf("\nout %s\n\n", __FUNCTION__)

/* 生成一个长度为len的数组, 其中array[i] = i(0<=i<len) */
void generate_array(int array[], int len);
    
/* 向长度为len的有序数组中新增一个元素x(0<=x<len - 1), 同时保持原有数组有序 */
void add_to_array(int array[], int len, int x);

/* 删除长度为len的有序数组中的一个元素x(0<=x<len), 同时保存原有数组有序 */
void del_from_array(int array[], int len, int x);

/* 打印一个数组 */
void display_array(int array[], int len);

/* 查找一个长度为len的有序数组中哪个元素不存在 */
int find_not_exist(int array[], int len);

/* 查找一个长度为len的有序数组中哪个元素重复了 */
int find_duplicate(int array[], int len);

int main(int argc, char *argv[])
{
    int count = 10;
    int *array = NULL;

    srand(time(NULL));

    if (argc == 2)
    {
        count = atoi(argv[1]);
    }

    /* 申请内存的时候多申请一个元素 */
    if ((array = (int *)malloc((count + 1) * sizeof(int))) == NULL)
    {
        printf("malloc error!\n");
        exit(-1);
    }

    /* 首先生成一个元素都是有序的整型数组 */
    generate_array(array, count);

    display_array(array, count);

    /* 删除其中的一个元素 */
    del_from_array(array, count, rand() % count);

    display_array(array, count);

    /* 查找不存在的元素 */
    int x = find_not_exist(array, count);
    printf("the element not exist is %d\n", x);

    /* 把删除的元素补上 */
    add_to_array(array, count + 1, x);

    /* 新增一个重复的元素 */
    add_to_array(array, count + 1, rand() % count);

    display_array(array, count + 1);

    /* 查找重复的元素 */
    printf("the element duplicate is %d\n", find_duplicate(array, count + 1));

    free(array);

    return 0;
}

void generate_array(int array[], int len)
{
    int i;

    for (i = 0; i < len; ++i)
    {
        array[i] = i;
    }
}

void add_to_array(int array[], int len, int x)
{
    int i;

    /* 把[x + 1, len - 1]之间的元素右移一个位置 */
    for (i = x + 1; i < len - 1; ++i)
    {
        array[i + 1] = i;
    }

    /* x + 1的位置保存重复的x, 这样数组仍然是有序的 */
    array[x + 1] = x;
}

void del_from_array(int array[], int len, int x)
{
    int i;

    /* 将[x, len)的元素向左移动一个位置 */
    for (i = x; i < len; ++i)
    {
        array[i] = i + 1;
    }

    printf("del_from_array element is %d\n", x);
}

void display_array(int array[], int len)
{
    int i;

    printf("\n{ ");
    for (i = 0; i < len; ++i)
    {
        printf("%d ", array[i]);
    }

    printf("}\n");
}

int find_not_exist(int array[], int len)
{
    FUNC_IN();

    int left, right, pos, count;

    for (left = 0, right = len - 1, count = 1; left <= right; count++)
    {
        pos = (left + right) / 2;

        printf("[%d] left = %d, pos = %d, right = %d\n", count, left, pos, right);

        /*
         * 如果array[pos] != pos, 那么不存在的元素一定在[left, pos - 1]之间
         */
        if (array[pos] != pos)
        {
            right = pos - 1;
        }
        else
        {
            left = pos + 1;
        }
    }

    FUNC_OUT();

    /* left之前的元素都是存在的 */
    return left;
}

int find_duplicate(int array[], int len)
{
    /*
     * find_not_exist()函数的返回值表示在它之前的元素都是正确的, 
     * 因此这个返回位置就是有重复的元素位置 + 1, 于是要减去1
     * */
    return find_not_exist(array, len) - 1;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值