基于快排的区间K值算法

#include <cstdio>
#include<iostream>
#include<stdlib.h>
using namespace std;
int n;
int QuickSort(int *a,int left,int right);
int search(int *a,int i,int j,int k);
void swap(int *a,int *b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
int main()
{
    int k_max;
    int a[100];
    cin >> n ;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    cin >> k_max;
    cout << search(a,1,n,k_max)<<endl;
  //  for (int i = 1; i <= n; ++i)
        //printf("%d	",a[i]);
  //  printf("\n");
    system("pause"); 
    return 0;
}
/*一次快速排序,返回被定位元素的位置,快排过程中关键元素始终不变*/
int QuickSort(int *a,int left,int right)
{
    int i,j,temp;
    i=left;
    j=right;
    temp=a[left];
    if (left>right)
        return -1;
    /*一前一后往中间搜索*/
    while (i!=j)
    {
        while (a[j]>=temp && j>i)
            j--;
        /*并没有交换,因只需找到某个确定位置即可*/
        if (j>i)
        {
            //a[i++]=a[j];
            swap(a+i,a+j);
            /*cout<<a[i]<<a[j];发现输出了很多数 */
            i++;
        }//必须加上大括号
        //for (int i = 1; i <= n; ++i)
           // printf("%d	",a[i]);
       // printf("\n");
        while (a[i]<=temp && j>i)
            i++;
        if (j>i)
        {
            //a[j--]=a[i];
            swap(a+j,a+i);
            j--;
        } //必须加上大括号
       // for (int i = 1; i <= n; ++i)
       //     printf("%d	",a[i]);
       // printf("\n");
    }
    a[i]=temp;
    return i;
}
//分治查找第k大的元素
int search(int *a,int i,int j,int k)
{
    int temp;
    if (j < i)
    {
        return -1;
    }
    if (i == j)
    {
        return a[i];
    }
    //得到第i个元素被定位的下标
    temp = QuickSort(a,i,j);
    //相等说明找到第k个大的元素
    if (temp == k)
    {
        return a[k];
    }
    //比k大,往左缩小查找范围
    else if (temp > k )
    {
        return search(a,i,temp-1,k);
    }
    /*比k小,往右缩小超找范围,注意此时k不是k-temp */
    else
    {
        return search(a,temp+1,j,k);
    }
}

 

posted @ 2012-06-09 15:50  加拿大小哥哥  阅读(220)  评论(0编辑  收藏  举报