69,371
社区成员
发帖
与我相关
我的任务
分享
//放回数组pArr中第二大的元素的下标。
int findElemAt(int * pArr ,int length)
{
//max_index始终指向最大元素,second_max_index始终指向第二大元素。
int max_index = 0 , second_max_index = 1;
assert(length>=2);
//调整max_index和second_max_index,初始化;
max_index = pArr[0] > pArr[1] ? 0 : 1 ;
second_max_index = !max_index;
for(size_t i = 2 ;i < length ;i++)
{
if(pArr[i] > pArr[second_max_index])
{
if(pArr[i] > pArr[max_index])
{
second_max_index = max_index ;
max_index = i;
}
else
{
second_max_index = i;
}
}
}
return second_max_index;
}
//找1个数组中第K大的数
//利用快排分区,实现类似折半查找
#include <iostream>
using namespace std;
bool findk(int* data, int num, int k, int* out);
int partition(int* data, int low, int high);
int main()
{
int data[] = {1, 7, 4, 8, 5, 6, 3, 2, 0, 9};
int num = sizeof(data) / sizeof(int);
int k = 2; //第k大
int result;
if (findk(data, num, k, &result))
cout << result << endl;
else
cout << "not find\n";
return 0;
}
bool findk(int* data, int num, int k, int* out)
{
if (num <= 0 || k <= 0 || k > num)
return false;
int pos = num - k; //从小到大排序好的数组第pos个下标的数就是第k大的数
//初始边界
int low = 0;
int high = num - 1;
int middle = partition(data, low, high);
while (middle != pos)
{
if (middle < pos) //返回坐标小,往右边找
{
low = middle + 1;
middle = partition(data, low, high);
}
else //返回坐标大,往左边找
{
high = middle - 1;
middle = partition(data, low, high);
}
}
*out = data[middle];
return true;
}
int partition(int* data, int low, int high) //快排分区函数
{
if (low == high)
return low;
int i, j, temp;
i = (low + high) / 2;
temp = data[i]; //取中间位置的值做为目标值
data[i] = data[low]; //把第一个放在中间
i = low;
j = high;
while (i < j)
{
while (temp < data[j] && i < j) //从右往左扫描小于目标的值,应该放在左半部分
j--;
if (i < j) //找到后放在左边
data[i++] = data[j];
else
break;
while (temp > data[i] && i < j) //从左往右扫描大于目标的值,要放在右边
i++;
if (i< j)
data[j--] = data[i];
else
break;
}
data[i] = temp; // i = j,正好是分界线,回填目标值
return i;
}
static void Main(string[] args)
{
int[] arr = new int[] {2,5,4,1,3,7,9,6,8 };
Console.WriteLine(arr.Except(new int[] { arr.Max() }).Max());
Console.ReadLine();
}