泛型程式設計與C++標準模板庫 : 淺談sort()排序函數,淺談sort
以前用sort排序的時候,只知道sort函數有如下兩種重載方式.
當時對這些參數也不是很懂,只知道一些簡單的用法.
1).比如: 如下代碼可以使數組a從小到大有序排列.
int a[5] = {1,6,9,4,5};
sort(a,a+5);
2).如下代碼可以使用自己設定的排序方式進行排序.
bool cmp(int a, int b)
{
return a > b;
}
int main()
{
int a[5] = {4,3,2,7,8};
sort(a,a+5,cmp);
return 0;
}
當然,sort()函數需要包含演算法標頭檔#include<algorithm>.
接下來,我們簡單分析一下sort()函數的實現:
我們首先看一下sort()源碼,這裡截個圖,1:
通過,可以清晰的看出,模板庫裡面的sort()排序還是比較複雜的,裡面嵌套了 快排,堆排,插入幾種不同的排序方法,同時,會根據不同的資料,調用不同的排序方案,以達到相對較快的排序目的.
當然,我們這裡只是簡單的分析一下,sort()原始碼.為了能說明白,我們將步驟劃分為了幾步,一步一步的分析.
第一步:這裡就不用模板庫的快排堆排了,為了簡單起見,直接上冒泡:
//////////////////////////////////////Date : 2014年8月1日14:14:35///IDE : VS2010///Author : Dujun Qing////////////////////////////////////1).簡單的冒泡排序#include <iostream>using namespace std;void maopao(int a[], int len){int i,j;int t = 0;for (i = 1; i < len; ++i){for (j = 0; j < len-1; ++j){if (a[j] > a[j+1]){t = a[j];a[j] = a[j+1];a[j+1] = t;}}}}int main(void){int i, a[] = {17,82,37,89,42,76,67,15};int len = sizeof(a)/sizeof(a[0]);maopao(a,len);for (i = 0; i < len; ++i){cout<<a[i]<<" ";}cout<<endl;return 0;}
第二步:用冒泡排序,類比sort()函數的兩種重載方式,第二種重載方式明顯要引入函數指標.
//2).引入函數指標#include <iostream>using namespace std;//比較函數bool Max(int a, int b){return a < b;}//bool (*cmp)(int, int):一個函數指標//表示指向的函數類型為:傳回值為bool,同時需要兩個int參數void maopao(int a[], int len, bool (*cmp)(int, int)){int i,j;int t = 0;for (i = 1; i < len; ++i){for (j = 0; j < len-1; ++j){if (cmp(a[j], a[j+1])) //注意此處直接調用函數--傳參,獲得傳回值{t = a[j];a[j] = a[j+1];a[j+1] = t;}}}}int main(void){int i, a[] = {17,82,37,89,42,76,67,15};int len = sizeof(a)/sizeof(a[0]);maopao(a,len,Max); //第3個參數(函數名):為比較方法for (i = 0; i < len; ++i){cout<<a[i]<<" ";}cout<<endl;return 0;}第三步:將上述代碼,模板化,使其能支援多種類型的資料排序.
//3).引入模板概念,支援多種類型#include <iostream>using namespace std;//比較函數template<class T>bool Max(T a, T b){return a > b;}//函數模板template<class T, class Func>void maopao(T a[], int len, Func cmp){int i,j;T t;for (i = 1; i < len; ++i){for (j = 0; j < len-1; ++j){if (cmp(a[j], a[j+1])) //注意此處直接調用函數--傳參,獲得傳回值{t = a[j];a[j] = a[j+1];a[j+1] = t;}}}}//重載函數模板,預設按從小到大排序template<class T>void maopao(T a[], int len){int i,j;T t;for (i = 1; i < len; ++i){for (j = 0; j < len-1; ++j){if (a[j] > a[j+1]) {t = a[j];a[j] = a[j+1];a[j+1] = t;}}}}int main(void){int i, a[] = {17,82,37,89,42,76,67,15};int len = sizeof(a)/sizeof(a[0]);//maopao(a, len); //預設按照,從小到大排序maopao(a,len,Max<int>); //第3個參數(函數名):為比較方法for (i = 0; i < len; ++i){cout<<a[i]<<" ";}cout<<endl;return 0;}第四步:上面幾步基本上已經實現了模板庫sort()函數的功能了,但是傳入的參數好像不對,為此我們再做如下調整改變,同時將冒泡排序替換為快排.
//3).修改排序函數,使其符合sort(a, a+10),sort(a, a+10,cmp)模式,同時將冒泡改為快排//系統的sort()函數有2種重載方式//1.sort(迭代器1, 迭代器2);//2.sort(迭代器1, 迭代器2, 謂詞方法);//說明:其實sort()函數所選擇的排序方法是比較複雜的,包括(快排,堆排,插入排序).//並且sort()會根據不同的資料而選擇不同的排序方案,我們這裡只以快排為例.#include <iostream>using namespace std;//比較函數template<class T>bool Max(T a, T b){return a > b;}//函數模板(採用快速排序)template<class T, class Func>void Qsort(T *begin, T *end, Func cmp){T t = *begin;T *pL = begin, *pR = (end-1);if (pL >= pR){return;}else{while (pL < pR){while (cmp(t, *pR) && pL < pR) {--pR;}*pL = *pR;while (cmp(*pL, t) && pL < pR){++pL;}*pR = *pL;}*pL = t;}Qsort(pL+1,end,cmp);Qsort(begin,pR-1,cmp);}//重載函數模板,預設一種排序方案(小到大)template<class T>void Qsort(T *begin, T *end){T t = *begin;T *pL = begin, *pR = (end-1);if (pL >= pR){return;}else{while (pL < pR){while (t < *pR && pL < pR) {--pR;}*pL = *pR;while (*pL <= t && pL < pR){++pL;}*pR = *pL;}*pL = t;}Qsort(pL+1,end);Qsort(begin,pR-1);}int main(void){int i, a[] = {17,82,37,89,42,76,67,15};int len = sizeof(a)/sizeof(a[0]);//Qsort(a,a+len);Qsort(a,a+len,Max<int>);for (i = 0; i < len; ++i){cout<<a[i]<<" ";}cout<<endl;return 0;}
原文地址:http://blog.csdn.net/qingdujun/article/details/38342951
編寫一個sort函數,它用於對任何類型的數組進行排序
如下,為了簡便,程式中使用了一些標準庫函數,所以需要包含兩個標頭檔,sort()函數利用選擇排序演算法對數組進行排序,調用時需要傳入的參數和標準庫函數qsort()一致
#include <stdlib.h>
#include <string.h>
void sort(void *base,unsigned int n,unsigned int width,int (*comp)(void *a,void *b))
{
char *p=(char *)base;
char *te=(char *)malloc(width);
char *ptr;
char *pn=p+width;
const char *cp=p+(n-1)*width;
for (; p<cp; p+=width) {
ptr=p;
for (pn=p+width; pn<=cp; pn+=width)
if ((*comp)(ptr,pn)>0) ptr=pn;
if (ptr!=p) {
memcpy(te,p,width);
memmove(p,ptr,width);
memmove(ptr,te,width);
}
}
free(te);
}
c++STL泛型程式設計sort演算法問題
你是指的是在sort泛型演算法中帶的參數有個謂詞吧。謂詞相當於sort中的1個參數,但是謂詞本身是個函數,你這裡的是個返回bool類型的函數,這個函數有2個參數,分別是對形參a和b的const引用,然後比較a和b是否相等,如果a不等於b,那麼return a>b 返回的是運算式a>b的值,如果a比b大,值的true,否則值為false ,else return a>b 這裡就是a==b的情況下才走到這裡,肯定返回false了
在sort演算法裡調用如下,比如定義了1個int的vector容器
vector<int> ivec;
sort(ivec.begin(),ivec.end(),Comp);
這裡記住Comp後面不能帶參數了,直接寫函數名字即可,在排序的時候就會根據函數的返回結果為true的進行排序,也就是說從大到小排序。