排序算法总结-插入排序、希尔排序、堆排序、快速排序
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);
}
今天就写到这里吧,上面的我都试了一下可以正常工作。睡觉了
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);
}
今天就写到这里吧,上面的我都试了一下可以正常工作。睡觉了
相关文章推荐
- 排序算法总结-插入排序、希尔排序、堆排序、快速排序
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 数据结构与算法:七种排序算法总结(冒泡排序、选择排序、直接插入排序、希尔排序、堆排序、归并排序、快速排序)
- 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 排序总结JS版(冒泡排序、简单选择排序、快速插入排序、希尔排序、堆排序、快速排序)
- 各种排序算法实现——基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 几种常见的排序算法(插入排序,希尔排序,归并排序和快速排序)——希尔排序
- 常见排序算法的实现(归并排序、快速排序、堆排序、选择排序、插入排序、希尔排序)
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 各排序算法总结(简单选择,冒泡,快速,希尔排序,堆排序)
- 常用的排序算法(快速排序、插入排序、希尔排序、堆排序、冒泡排序、选择排序、归并排序)
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结
- 七大内部排序算法总结(插入排序、希尔排序、冒泡排序、简单选择排序、快速排序、归并排序、堆排序)
- 面试珠玑 快速排序、希尔排序、插入排序、选择排序、归并排序、堆排序总结