【算法导论】中位数

一、选择法排序、冒泡排序、插入法排序

二、快速排序、分治法排序、堆排序

三、计数排序、基数排序、桶排序

gtest介绍及测试用例如下:测试框架之GTest

MIT《算法导论》下载:hereorhttp://download.csdn.net/detail/ceofit/4212385

源码下载:here orhttp://download.csdn.net/detail/ceofit/4218488

 

中位数

中位数用于查找序列中指定大小位置的数值。包括求最大值、最小值、中间指定第pos小的值。

最大值、最小值比较简单,在排序算法 零中已有介绍。

不多说了,代码很简单,大家一看就懂,时间复杂度n,空间复杂度1

int get_max(int *pArray,int cnt)
{
    if(cnt <= 0)
        return 0;
    int max = pArray[0];
    int i = 0;
    for(i=1; i<cnt; i++)
    {
        max = max>=pArray[i] ? max : pArray[i];
    }
    return max;
}

int get_min(int *pArray,int cnt)
{
    if(cnt < 0)
        return 0;
    int min = pArray[0];
    int i = 0;
    for(i=1; i<cnt; i++)
    {
        min = min<=pArray[i] ? min : pArray[i];
    }
    return min;
}

求指定位置pos的数值也有很多方法,最直接的就是排序,排序后直接取下标,但时间复杂度、空间复杂度与排序算法一致,且原序列发生了变化。

也可借助快速排序的思想,可得到最优情况下时间复杂度平均为n,空间复杂度为1的算法。而最坏情况下时间复杂度为n*n。

由于快排最坏情况下时间复杂度为n*n,因此前面提出了随机化快速排序的方法,可使时间复杂度接近nlgn。

而此处的中位数查找,使用随机化的思想,可使时间复杂度接近n。

前面讲过,快排的原理是比如将第1个数值,一层排序可直接找到其位置,然后对齐高位、低位分别递归。利用这个一步到位的思想,在递归的过程中,如果得到位置为pos的数值直接返回即可。为优化速度,递归过程中不需要按照快排高低位都递归,只需递归一边即可。

#include "SK_Common.h"
#include "SK_Sort.h"

//将第1个元素移动到指定位置,且保证小于此元素的在其左边,大于的在其右边
static int get_middle(int *pArray,int start,int end)
{
	if(start >= end)
		return start;
	int midvalue = pArray[start];
	int save_ptr = start;
	int front_ptr = start;
	
	while(front_ptr <= end)
	{
		if(pArray[front_ptr] < midvalue)
		{
			pArray[save_ptr] = pArray[front_ptr];
			pArray[front_ptr] = pArray[save_ptr+1];
			save_ptr++;
		}
		front_ptr++;
	}
	pArray[save_ptr] = midvalue;
	return save_ptr;
}


//随机化方法,查找随机位置,与第1位交换。
int get_middle_random(int *pArray,int start,int end)
{
	int mid = get_random(start,end);
	exchange(pArray+start,pArray+mid);
	return get_middle(pArray,start,end);
}

int _quick_search(int *pArray,int start,int end,int pos)
{
    if(start >= end)
        return pArray[end];
    int mid = get_middle_random(pArray,start,end);
    if(mid == pos)          //找到
        return pArray[mid];
    else if(pos < mid)      //pos在低位
        return _quick_search(pArray,start,mid-1,pos);
    else                    //pos在高位
        return _quick_search(pArray,mid+1,end,pos);
}

int QuickSearch(int *pArray,int cnt,int pos)
{
    if(cnt <= 0)
    {
        return 0;
    }
    if(pos > cnt)
        pos = cnt;

    return _quick_search(pArray,0,cnt-1,pos-1);
}

随机情况下时间复杂度平均为n,空间复杂度为1,但原始序列发生了改变。

如果要求原始序列不变,可复制一份,以备份查找,空间复杂度n。

时间复杂度平均为n的计算方法在书中介绍的很详细,且公式比较多,大家有兴趣的花翻书看看。

你可能感兴趣的:(框架,算法,测试,search,Random,Exchange)