您的位置:首页 > 其它

排序算法总结-插入排序、希尔排序、堆排序、快速排序

2014-03-23 11:18 260 查看
今天去面试被问到了自己知道哪些排序算法,虽然答了一堆,但是想想会的真没几个,所以回来后这里将几个(自认为)重要的写在这里。

1、插入排序

[cpp] view plaincopy





//插入排序

//原理:前i项是排过序的,将当前元素插入到前面已经排过序的序列中

//时间界:O(N2)

template <</SPAN>typename Comparable>

void insertionSort(vector &a){

for( size_t i = 1; i < a.size(); i++){

Comparable temp = a[i];

int j;

for(j = i; j > 0 && temp < a[j - 1]; j--){

//如果当前待插入的元素小于前面的元素,

//则依次后移

a[j] = a[j - 1];

}

//将当前带插入元素放到循环退出的位置

//即前面的元素没有他大,或者j已经到了第一个位置

a[j] = temp;

}

}

2、希尔排序

[cpp] view plaincopy





//希尔排序

//原理:所有相隔某个增量的元素都被排序

//时间界与选取的增量序列相关,一般好于插入排序,但大于NlogN

int getGap(int num){

int power = 0;

while((num/=2) > 0){

power++;

}

return (int)pow((double)2,(double)power);

}

template<</SPAN>typename Comparable>

void shellSort(vector &v){

//这里选取增量序列为1,3,7,...,pow(2,k)-1

int gap = getGap(v.size());

for(; gap > 0; gap = gap/2 - 1){

for( size_t i = gap; i < v.size(); i++){

Comparable temp = v[i];

int j = i;

//我感觉这里跟插入排序是一样的,插入排序可以理解为gap是1的情况。

for(j = i; j >= gap && temp < v[j - gap]; j -= gap)

v[j] = v[j - gap];

v[j] = temp;

}

}

}

3、堆排序

[cpp] view plaincopy





//堆排序

//根据二叉堆而来,这里用最大堆,即根的键值比其儿子的键值大

//通过deleteMax操作得到排序后的序列

template<</SPAN>typename Comparable>

//下率操作

void percDown(vector &v, int current, int n){

Comparable temp;

int child;

for( temp = v[current]; 2*current < n; current = child){

child = 2*current;

//找到最大的孩子

if( child + 1 < n && v[child] < v[child+1])

child++;

//如果最大的孩子比父亲大,则交换,否则找到了正确的位置退出

if( v[child] > temp)

v[current] = v[child];

else

break;

}

//将传进来的位置上的键值放到找到的位置

v[current] = temp;

}

template<</SPAN>typename Comparable>

void heapSort(vector &v){

for( int i = v.size()/2; i >= 0; i--){

percDown(v, i, v.size());

}

for(size_t j = v.size() - 1; j > 0; j--){

//这里将最大的值与最后一个元素互换,即deleteMax操作

Comparable temp = v[0];

v[0] = v[j];

v[j] = temp;

//然后对根处的元素进行下率

percDown( v, 0, j);

}

}

4、快速排序

[cpp] view plaincopy





//快速排序

//主要需要找到枢纽元,然后对其进行分段排序

//找到枢纽元的方法可以自己进行各种改进

template<</SPAN>typename Comparable>

void swap(vector &v, int i, int j){

Comparable temp = v[i];

v[i] = v[j];

v[j] = temp;

}

template<</SPAN>typename Comparable>

int getPivot(vector &v, int low, int high){

int middle = (low + high)/2;

if( v[low] > v[middle]){

swap(v, low, middle);

}

if( v[low] > v[high]){

swap(v, low, high);

}

if( v[middle] > v[high]){

swap(v, middle, high);

}

//这里将选出的中间值放在倒数第二个位置,因为最后一个不用再筛选了,他肯定比中间值大

swap(v, middle, high - 1);

return v[high - 1];

}

template<</SPAN>typename Comparable>

void quickSort(vector &v, int low, int high){

if( low >= high)

return;

Comparable pivot = getPivot( v, low, high);

int l = low;

int r = high - 1;

while(1){

//当遇到不满足条件的元素时,l和r分别指向他们

while(v[++l] < pivot){}

while(v[--r] > pivot){}

if( l < r){

swap( v, l, r);

}else{

break;

}

}

//将枢纽元放置到结束的地方

swap(v, l, high - 1);

quickSort( v, low, l -1);

quickSort( v, l + 1, high);

}

今天就写到这里吧,上面的我都试了一下可以正常工作。睡觉了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐