求无序数组中元素出现次数超过数组长度一半的数字.
首先给出几个"元素出现次数超过数组长度一半"测试数组:
a1[7]={1 ,2, 3 , 5 , 3 , 3 , 3};
a2[5]={5, 3, 5, 5, 1};
a3[9]={8 ,5 ,6 ,5 ,4 ,2 ,5 ,5 ,1};
不难发现:
数组中如果一个数字出现次数超过数字长度的一半.如果把这个数组排序,那么排序后的数组中间的数字一定是出现次数超过数字长度的一半.
如数组a1长度为7,按从小到大排序后为a1[7]={1,2,3,3,3,3,5},此时数组中间的数字a[7/2]=2就是要找的数字.
如数组a2长度为5,按从小到大排序后为a2[5]={1,3,5,5,5},此时数组中间的数字a[5/2]=5就是要找的数字.
如数组a3长度为9,按从小到大排序后为a3[9]={1,2,4,5,5,5,5,6,8},此时数组中间的数字a[9/2]=5就是要找的数字.
所以有了以上的发现,我们就可以先随机选择数组中的一个数字,然后进行排序,使比它小的数字位于它左边,使比它大的数字位于它右边.
如果选中的这个数下标恰好是n/2,那么这个数字就是数组的中位数,
如果它的下标大于n/2,那么它的下标大于n/2,那么中位数在它的左边,我们便可以继续在左边递归查找,
如果它的下标小于n/2,那么它的下标小于n/2,那么中位数在它的右边,我们便可以继续在右边递归查找.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int qort(int arr[], int left, int right)
{
int tmp = arr[left];
while (left < right)
{
while (left < right && arr[right] >= tmp)
{
right--;
}
if (arr[right] < tmp)
{
arr[left] = arr[right];
arr[right] = tmp;
}
while (left<right && arr[left] <= tmp)
{
left++;
}
if (arr[left]>tmp)
{
arr[right] = arr[left];
arr[left] = tmp;
}
}
return right;
}
int SelectHalfNum(int *arr,int len)
{
int left = 0;
int right = len-1;
int tem = qort(arr, left, right);
int middle = len / 2;
while (tem != middle)
{
if (tem > middle)
{
right = tem - 1;
tem = qort(arr, left, right);
}
else
{
left = tem + 1;
tem = qort(arr, left, right);
}
}
printf("%d\n", arr[middle]);
}
int main()
{
int arr[] = {1,2,2,5,2};
int len = sizeof(arr) / sizeof(arr[0]);
SelectHalfNum(arr, len);
system("pause");
return 0;
}
以上代码有个Bug,那就是应该对数组进行判断,判断数组是否存在出现次数大于数组长度的元素.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int qort(int arr[], int left, int right)
{
int tmp = arr[left];
while (left < right)
{
while (left < right && arr[right] >= tmp)
{
right--;
}
if (arr[right] < tmp)
{
arr[left] = arr[right];
arr[right] = tmp;
}
else
{
break;
}
while (left<right && arr[left] <= tmp)
{
left++;
}
if (arr[left]>tmp)
{
arr[right] = arr[left];
arr[left] = tmp;
}
else
{
break;
}
}
return right;
}
int CheckNum(int *arr, int len, int val)
{
int cout = 0;
int i = 0;
for (i = 0; i < len; i++)
{
if (arr[i] == val)
{
cout++;
}
}
if (cout > len/2)
{
return 1;
}
return 0;
}
int SelectHalfNum(int *arr, int len)
{
int left = 0;
int right = len - 1;
int tem = qort(arr, left, right);
int middle = len / 2;
while (tem != middle)
{
if (tem > middle)
{
right = tem - 1;
tem = qort(arr, left, right);
}
else
{
left = tem + 1;
tem = qort(arr, left, right);
}
}
int ret = arr[middle];
if (CheckNum(arr,len,ret)!=0)
{
return ret;
}
return 0;
}
int main()
{
int arr[] = { 1, 2, 5, 2 };
int len = sizeof(arr) / sizeof(arr[0]);
printf("%d", SelectHalfNum(arr, len));
system("pause");
return 0;
}