快速排序及寻找最小的k个数

来源:互联网 发布:sql with cte as 编辑:程序博客网 时间:2024/04/19 19:19

快速排序

快速排序采用的是分治策略在一个list中选择一个基准值(pivot  value),将list中比基准值小的元素排在基准值的左侧,比基准值大的元素排在基准值的右侧,形成两个sub-list;然后对sub-list进行同样的操作,直至整个list排序完成。

Partition伪代码

// pseudocode of Partitionfunction Partition(a, left, right)pivotIndex := (left + right) / 2;pivotValue := a[pivotValue];storeIndex := left;for i from left to right-1if a[i] < pivotValueswap(a[i], a[storeIndex]);storeIndex := storeIndex;swap(a[right], a[storeIndex]);return storeIndex;


pivotIndex有多种选择方式,这里采用list的中间index作为pivotIndex .

storeIndex是所有小于pivotValue的元素的后面一个index,每次交换就是a[storeIndex]a[i].

 

Quicksort伪代码

// psedocode of Quicksortfunction Quicksort(a, left, right)if right > leftpivotIndex := Partition(a, left, right);Quicksort(a, left, pivotIndex-1);Quicksort(a, pivotIndex+1, right);



寻找最小的k个数

与快速排序类似,仍然采用分治策略,不同的是,不必对每个sub-list都进行partition, 只对需要的sub-list进行partition。执行结束后,最小的k个数排在数组的前k个位置,但是,这k个数可能并没有经过排序。

算法导论第9章有该算法的实现:



代码:

template<typename Type>void my_swap(Type& a, Type& b){Type tmp = a;a = b;b = tmp;} template<typename Type>int partition(Type* a, int left, int right){int pivotIndex = (left + right)/2;int storeIndex = left;Type pivotValue = a[pivotIndex];my_swap(a[pivotIndex], a[right]);for(int i = left; i < right; i++){if(a[i] < pivotValue){swap(a[i], a[storeIndex]);storeIndex ++;}}my_swap(a[storeIndex], a[right]);return storeIndex;}template<typename Type>void my_quick_sort(Type* a, int left, int right){if(right > left){int pivotIndex = partition(a, left, right);my_quick_sort(a, left, pivotIndex-1);my_quick_sort(a, pivotIndex+1, right);}}template<typename Type>void my_select(Type* a, int p, int r, int i){if(p == r)return;int q = partition<Type>(a, p, r);int k = q - p + 1;if(i == k)return;else if(i < k)my_select(a, p, q-1, i);elsemy_select(a, q+1, r, i-k);}

参考:

[1] http://zh.wikipedia.org/zh-cn/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F

[2] 算法导论,第三版,第9章

0 0
原创粉丝点击