设为首页 加入收藏

TOP

求一个无序数组中第k小的数字(一)
2014-11-24 01:43:23 来源: 作者: 【 】 浏览:32
Tags:一个 序数 数字

算法思想:找一个点,然后放到末尾,然后将小于这个数的值放在数组前面,大于这个值的放在数组后面,然后在将这个末尾的数放回。这个末尾数放入的位置i代表已经找到第i小的数,放入的位置如果是k,就找到了第k小的数


同样找到第k大的数类似的解法,找到前k个最大数也一样。找一个数组的中位数也一样做。求n个数组的中位数也一样的做。求n个数组的前k个大数或小数也类似可以做。


代码:










/***************************************
输入: n:数组元素的个数 k:第几大的数
a:待查找的数组元素
****************************************/
#include
#include
#include


#define N 100


void Rand_select( int*, int, int );
int partition( int*, int, int );
int swap( int&, int& );
int k, ans;


int main()
{
int n, a[N], i;
while( scanf( “%d%d”, &n, &k ) != EOF )
{
srand(time(NULL));
k–;
for( i = 0; i < n; i++ )
scanf( “%d”, a + i );
Rand_select( a, 0, n-1 );
printf( “%d\n”, ans );
}
return 0;
}


void Rand_select( int a[], int p, int q )
{
int m;
if (p <= q)
{
m = partition( a, p, q );
if( k == m )
{ ans = a[m]; return; }
else if( k > m )
Rand_select( a, m+1, q );
else
Rand_select( a, p, m-1 );
}
}


int partition( int a[], int p, int q )
{
int last, i;
if( q != p )
swap( a[rand()%(q-p)+p], a[p] );
for( i = p+1, last = p; i <= q; i++ )
if( a[i] >= a[p] )
swap( a[i], a[++last] );
swap( a[last], a[p] );
return last;
}


int swap( int &p, int &q )
{
int temp = p;
p = q;
q = temp;
return 0;
}



#include ;
using namespace std;


void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}


int k_smallest(int k, int a[], int left, int right)
{
int pivot = a[right]; //the last item as pivot
int i = left;
int j = right-1;
for(;;)
{
for(; a[i] for(; a[j]>;=pivot; j–);
if(i swap(a[i], a[j]);
else
break;
}
swap(a[i], a[right]);
//now i is the pivot index in the array
//i.e. a[i] is the (i+1)th smallest item


if(k==i-left+1)
return a[i];
else if(k < i-left+1) //target before pivot
return k_smallest(k, a, left, i-1);
else //target after pivot
return k_smallest((k-(i-left+1)), a, i+1, right);
}


//find the k_th smallest item in the array
int Kth_smallest(int k, int a[], int size)
{
return k_smallest(k, a, 0, size-1);
}


int main()
{
int a[10] = {4, 8, 1, 5, 2, 9, 3, 7, 10, 6};


for(int i=1; i<=10; i++)
cout< }













可以先用快速排序进行排序,其中用另外一个进行地址查找
代码如下,在VC++6.0运行通过。给分吧^-^


//快速排序


#include


using namespace std;


int Partition (int *L,int low,int high)
{
int temp = L[low];
int pt = L[low];


while (low < high)
{
while (low < high && L[high] >= pt)
–high;
L[low] = L[high];
while (low < high && L[low] <= pt)
++low;
L[low] = temp;
}
L[low] = temp;


return low;
}


void QSort (int *L,int low,int high)
{
if (low < high)
{
int pl = Partition (L,low,high);


QSort (L,low,pl – 1);
QSort (L,pl + 1,high);
}
}


int main ()
{
int narry[100],addr[100];
int sum = 1,t;


cout << “Input number:” << endl;
cin >> t;


while (t != -1)
{
narry[sum] = t;
addr[sum - 1] = t;
sum++;


cin >> t;
}


sum -= 1;
QSort (narry,1,sum);


for (int i = 1; i <= sum;i++)
cout << narry[i] << ‘\t’;
cout << endl;


int k;
cout << “Please input place you want:” << endl;
cin >> k;


int aa = 1;
int kk = 0;
for (;;)
{
if (aa == k)
break;
if (narry[kk] != narry[kk + 1])
{
aa += 1;
kk++;
}


}


cout << “The NO.” << k << “number is:” << narry[sum - kk] << endl;
cout << “And it’s place is:” ;
for (i = 0;i < sum;i++)
{
if (addr[i] == narry[sum - kk])
cout << i << ‘\t’;
}


return 0;
}












这道题去年baidu笔试也出现过,当时写的是这个答案,高手分析下:
#include
#include
#include
#include
#include
using namespace std;


#define n 10
#define k 5


int main(int argc, char* argv[])
{
srand((unsigned )time(NULL));
if ( k > n )
{
cout << “error!” << endl;
return 1;
}
vector src;
cout << “源” << n << “个数据如下:” << endl;
for ( int i = 0; i < n; i++ )
{
src.push_back( rand() );
cout << src[i] << ” “;
}
vector maxNum; //顺序存入最大k个数,第一个为最大的,最后一个为第k大
for ( i = 0; i < k; i++ )
{
maxNum.push_back(-999999); //初始化maxNum,k个-9999999
}
for ( i = 0; i < n; i++ )
{
for ( int j = 0; j < maxNum.size(); j++ )
{
if ( src[i] >= maxNum[j] ) //比当前的大,则放入当前位置,后面的数字依次后退
{
for ( int i1 = maxNum.size()-1; i1 > j;

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇华为面试归来 完败+分享一下面试.. 下一篇编写类String的构造函数、析构函..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: