#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
// ^
// p
int 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
// ^
// p
int 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
// ^
// p
int 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;
}
求无需数组第K小的数及其位置
最新推荐文章于 2023-04-30 21:07:47 发布