求无需数组第K小的数及其位置

来源:互联网 发布:简单拼图软件 编辑:程序博客网 时间:2024/05/25 19:55
#include "stdafx.h"#include <time.h>#include <stdio.h>#include <stdlib.h>void swap(int & a, int & b);int find_position(int* a,int k, int low,int high);int find_orderk(int* a, int k, int low,int high);int MAXCOUNT = 10;void swap(int & a, int & b){    int tmp = a;    a = b;    b = tmp;}int get_position(int* a, int count,int value){    int pos = -1;    for ( int i = 0; i < count ; i++ )    {        if ( a[i] == value )        {            pos = i;        }    }    return pos;}void print_array(int* a, int count){    for ( int i = 0; i < count ; i++ )    {        if(i%10 == 0)            printf("\n");        printf("%d\t", a[i]);    }}//随机选取数组指定范围内的一个数Value,//把指定范围内的数以Value为分界点,左边部分大于等于Value,右边部分小于Value//返回所选数值所在的位置// a[low]... a[m]...a[hight]//             ^//  > value  value  < value//             ^//             pint find_position(int* a, int low,int hight){    //只有一个元素直接返回    if (low >= hight)    {        return low;    }        //随机选取low与hight之间的一个数作为基准    int m = rand() % (hight - low) + low;    int value =  a[m];      //选取元素的值    int p = m;              //选取元素的索引        int lowpos = low;       //第一个小于Value的元素索引    int hightpos = hight;   //最后一个大于Value的元素索引    bool bfindl = false;    //是否存在小于Value的元素    bool bfindh = false;    //是否存在大于Value的元素        for (int i = low; i <= hight; i++)    {                if(a[i] >= value && i != m)        {            bfindh = true; //存在大于Value的元素            if(bfindl)            {                //与第一个小于Value的元素交换                hightpos = lowpos;                swap(a[lowpos++], a[i]);                //跳过索引m的位置                if (lowpos == m)                {                    lowpos++;                }            }            else            {                hightpos = i;            }        }        //第一个小于Value的索引        else if( a[i] < value && !bfindl)        {            lowpos = i;            bfindl = true;        }    }        //存在大于Value的元素,并且最后一个大于Value的元素在m之后,需要交换    if(bfindh && hightpos > m)    {        swap(a[p], a[hightpos]);        p = hightpos;    }        //存在小于Value的元素,并且第一个小于Value的元素在m之前,需要交换    if(bfindl && lowpos < m)    {        swap(a[p], a[lowpos]);        p = lowpos;    }    return p;}//随机选取数组指定范围内的一个数Value,//把指定范围内的数以Value为分界点,左边部分大于等于Value,右边部分小于Value//返回所选数值所在的位置// a[low]... a[m]...a[hight]//             ^//  > value  value  < value//             ^//             pint find_position_h(int* a, int low,int hight){    //只有一个元素直接返回    if (low >= hight)    {        return low;    }        //随机选取low与hight之间的一个数作为基准    int m = rand() % (hight - low) + low;    int value =  a[m];      //选取元素的值    int p = m;              //选取元素的索引        int lowpos = low;       //第一个小于Value的元素索引    int hightpos = hight;   //最后一个大于Value的元素索引    bool bfindl = false;    //是否存在小于Value的元素    bool bfindh = false;    //是否存在大于Value的元素        for (int i = low; i <= hight; i++)    {                if(a[i] >= value && i != m)        {            bfindh = true; //存在大于Value的元素            if(bfindl)            {                //与第一个小于Value的元素交换                hightpos = lowpos;                swap(a[lowpos++], a[i]);                                //跳过索引m的位置                if (lowpos == m)                {                    lowpos++;                }            }            else            {                hightpos = i;            }        }        //第一个小于Value的索引        else if( a[i] < value && !bfindl)        {            lowpos = i;            bfindl = true;        }    }        //存在大于Value的元素,并且最后一个大于Value的元素在m之后,需要交换    if(bfindh && hightpos > m)    {        swap(a[p], a[hightpos]);        p = hightpos;    }        //存在小于Value的元素,并且第一个小于Value的元素在m之前,需要交换    if(bfindl && lowpos < m)    {        swap(a[p], a[lowpos]);        p = lowpos;    }    return p;}//随机选取数组指定范围内的一个数Value,//把指定范围内的数以Value为分界点,左边部分大于等于Value,右边部分小于Value//返回所选数值所在的位置// a[low]... a[m]...a[hight]//             ^//  < value  value  > value//             ^//             pint find_position_l(int* a, int low,int hight){    //只有一个元素直接返回    if (low >= hight)    {        return low;    }        //随机选取low与hight之间的一个数作为基准    int m = rand() % (hight - low) + low;    int value =  a[m];      //选取元素的值    int p = m;              //选取元素的索引        int hightpos = low;       //第一个大于Value的元素索引    int lowpos = hight;   //最后一个小于Value的元素索引    bool bfindl = false;    //是否存在小于Value的元素    bool bfindh = false;    //是否存在大于Value的元素        for (int i = low; i <= hight; i++)    {                if(a[i] <= value && i != m)        {            bfindl = true; //存在小于Value的元素            if(bfindh)            {                //与第一个大于Value的元素交换                lowpos = hightpos;                swap(a[hightpos++], a[i]);                print_array(a, MAXCOUNT);                //跳过索引m的位置                if (hightpos == m)                {                    hightpos++;                }            }            else            {                lowpos = i;            }        }        //第一个大于Value的索引        else if( a[i] > value && !bfindh)        {            hightpos = i;            bfindh = true;        }    }        //存在大于Value的元素,并且第一个大于Value的元素在m之前,需要交换    if(bfindh && hightpos < m)    {        swap(a[p], a[hightpos]);        print_array(a, MAXCOUNT);        p = hightpos;    }        //存在小于Value的元素,并且最后一个小于Value的元素在m之后,需要交换    if(bfindl && lowpos > m)    {        swap(a[p], a[lowpos]);        print_array(a, MAXCOUNT);        p = lowpos;    }        return p;}//获得数组指定范围【low,height】内第K大的数所在的位置int find_orderk(int* a, int k, int low,int hight){    //获得一个low与hight之间的一个位置p,使得a[low...p] >= a[p], a[p+1, hight] < a[p]    int p = find_position(a, low, hight);        //p与low索引之间的元素个数小于K    if(p-low < k-1)    {        //获得数组指定范围【p+1,height】内第【(k-1)-(p-low)】大的数所在的位置        p = find_orderk(a, (k-1)-(p-low), p+1, hight);    }    //p与low索引之间的元素个数大于K    else if (p-low > k-1)    {        //获得数组指定范围【low,p-1】内第【k】大的数所在的位置        p = find_orderk(a, k, low, p-1);    }    return p;}//获得数组指定范围【low,height】内第K大的数所在的位置int find_orderk_h(int* a, int k, int low,int hight){    //获得一个low与hight之间的一个位置p,使得a[low...p] >= a[p], a[p+1, hight] < a[p]    int p = find_position_h(a, low, hight);        //p与low索引之间的元素个数小于K    if(p-low < k-1)    {        //获得数组指定范围【p+1,height】内第【(k-1)-(p-low)】大的数所在的位置        p = find_orderk(a, (k-1)-(p-low), p+1, hight);    }    //p与low索引之间的元素个数大于K    else if (p-low > k-1)    {        //获得数组指定范围【low,p-1】内第【k】大的数所在的位置        p = find_orderk(a, k, low, p-1);    }    return p;}//获得数组指定范围【low,height】内第K小的数所在的位置int find_orderk_l(int* a, int k, int low,int hight){    //获得一个low与hight之间的一个位置p,使得a[low...p] <= a[p], a[p+1, hight] > a[p]    int p = find_position_l(a, low, hight);        //p与low索引之间的元素个数小于K    if(p-low < k-1)    {        //获得数组指定范围【p+1,height】内第【(k-1)-(p-low)】大的数所在的位置        p = find_orderk_l(a, (k-1)-(p-low), p+1, hight);    }    //p与low索引之间的元素个数大于K    else if (p-low > k-1)    {        //获得数组指定范围【low,p-1】内第【k】大的数所在的位置        p = find_orderk_l(a, k, low, p-1);    }    return p;}int main ()  {    srand((unsigned) time(NULL));        //初始化数组    int srcArray[100];    int keyArray[100];        int n;    do    {        printf("\n初始化数组,请输入数组元素个数(1-100):");        scanf("%d", &n);            }while ( n > 100 || n <= 0);    MAXCOUNT = n;    int i = 0;    while(i < n)    {        srcArray[i] = rand()%100;        keyArray[i]=srcArray[i];        i++;    }        //输出数组元素    print_array(srcArray, n);        //获得参数    do    {        int k = 1;        do        {            printf("\n请输入数值(1-%d):", n);            scanf("%d", &k);        }while ( k > n || k <= 0);                //获得第K大元素位置        int newpos = find_orderk_h(srcArray, k, 0, n-1);        int value = srcArray[newpos];        int srcpos = get_position(keyArray, n, value);        printf("\n 数组中第 %d 大的数值: %d 位置: %d \n", k, value, srcpos);        system("PAUSE");        memcpy(srcArray, keyArray, sizeof(srcArray));        //获得第n - k + 1小元素位置        int no = n - k + 1;        int newpos2 = find_orderk_l(srcArray, no, 0, n-1);        print_array(srcArray, n);        int value2 = srcArray[newpos2];        int srcpos2 = get_position(keyArray, n, value2);        printf("\n 数组中第 %d 小的数值: %d 位置: %d \n", no , value2, srcpos2);        system("PAUSE");        memcpy(srcArray, keyArray, sizeof(srcArray));    }while ( true );     return 0;}


原创粉丝点击