#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;}