求一个数组的第N小数。 基于快排序思想

/*
DEL
/*void swap(int &num1,int &num2)
{
    int iTemp = num1;
    num1 = num2;
    num2 = iTemp;
}    
int GetPos(int* piInt,int iStartIndex,int iEndIndex)
{
    int iPos = iStartIndex;
    int iPosValue = piInt[iStartIndex];
    int iLeftIndex = iPos + 1;
    int iRightIndex = iEndIndex;
    while(true)
    {
        if(piInt[iLeftIndex] < iPosValue && iLeftIndex <=iEndIndex)
        {
            iLeftIndex++;
        }
        if(piInt[iRightIndex] > iPosValue)
        {
            iRightIndex--;
        }
        if(iRightIndex < iLeftIndex)
        {
            break;
        }    
        swap(piInt[iLeftIndex],piInt[iRightIndex]);
                
    }    
    swap(piInt[iPos],piInt[iRightIndex]);
    return iRightIndex;
}    
int GetInputTh(int* piInt,int iStartIndex,int iEndIndex,int iInput)
{
    if(iStartIndex <= iEndIndex)
    {
    int iPos = GetPos( piInt,iStartIndex,iEndIndex);
    if(iPos + 1 == iInput)
    {
        return piInt[iPos];
    }    
    else if(iPos + 1 < iInput) //right
    {
        GetInputTh(piInt,iPos + 1,iEndIndex,iInput);
    }        
    else //left
    {
        GetInputTh(piInt,iStartIndex,iPos -1,iInput);
    }
   }            
}
 int aiTest[1000000];
int main()
{
 
    for(int i =0;i<1000000;i++)
        aiTest[i] = 1000000 -i;
    int iInput = 0;
    while( cin>>iInput )
    {
        int num = GetInputTh(aiTest,0,999999,iInput);
        cout<<num<<endl;
    }        
} */   

*DEL/

// d.cpp : 定义控制台应用程序的入口点。
// 随机快速排序,效果正好一些,避免常规排序最坏情况,堆栈溢出。快拍2000000不到1S吧
#include"stdafx.h"
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
int GetDiviedPosition(int* piScr,int iStartIndex,int iEndIndex)  
{  
    int iTemp = 0;  
    int iPos = iStartIndex;  
    int iPosValue = piScr[iPos];  
    int iLeftIndex = iPos + 1;  
    int iRightIndex = iEndIndex;  
    while(true)  
    {  
        while(iLeftIndex < iEndIndex && piScr[iLeftIndex] >iPosValue)  
        {  
            iLeftIndex ++;  
        }  
        while(piScr[iRightIndex] < iPosValue)  
        {  
            iRightIndex--;  
        }           
        if(iLeftIndex >= iRightIndex)  
        {  
            break;  
        }      
        else  
        {  
            iTemp = piScr[iLeftIndex];  
            piScr[iLeftIndex] = piScr[iRightIndex];  
            piScr[iRightIndex] = iTemp;   
        }      
    }  
    // swap piScr[iRightIndex] and piScr[iPos]  return the pos iRightIndex   
    piScr[iPos] = piScr[iRightIndex];  
    piScr[iRightIndex] = iPosValue;  
    return iRightIndex;   
}   
int GetPosRandom(int* piScr,int iStartIndex ,int iEndIndex)  
{  
    //generate a number between [iStartIndex,iEndIndex];  
    srand(time(NULL)); // seed the random-number generator with the current time   
    int iRand =(int)( ((double)rand()/(double)RAND_MAX )* (iEndIndex-iStartIndex))  + iStartIndex;   
    int iTemp = 0; 
    iTemp = piScr[iStartIndex];  
    piScr[iStartIndex] = piScr[iRand];  
    piScr[iRand] = iTemp;  
    return GetDiviedPosition(piScr,iStartIndex,iEndIndex); 
}     
int GetInputTh(int* piInt,int iStartIndex,int iEndIndex,int iInput)  
{  
    if(iStartIndex < iEndIndex)  
    {  

        int iPos = GetPosRandom( piInt,iStartIndex,iEndIndex); 
        if(iPos  + iInput - 1 == iEndIndex)  
        {  

            return piInt[iPos];  
        }      
        else if(iPos  < iEndIndex - iInput + 1) //right  
        {  
            GetInputTh(piInt,iPos + 1,iEndIndex,iInput);  
        }          
        else //left  
        {  
            GetInputTh(piInt,iStartIndex,iPos -1,iInput - (iEndIndex - (iPos -1)));  // 10 5 10 
        }  
    }   
    else
       return piInt[iEndIndex];
  
}  
int aiTest[3000000];  
int main()  
{  

    int iInput = 0; int n =0;   
   
    while(scanf("%d%d",&n,&iInput)==2)  
    {
        for(int i =1;i<=n;i++)
        {
            //scanf("%d",&aiTest[i]);
            aiTest[i] = i;
        }    
        int num = GetInputTh(aiTest,1,n, iInput);  
        printf("%d\n",num);
    }          
}   



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值