七大排序算法总结(含优化)

来源:互联网 发布:js获取电子秤串口数据 编辑:程序博客网 时间:2024/06/08 02:12
冒泡排序#include <cstdio>#define N 100using namespace std;int a[N];void bubbleSort(int n)        //冒泡排序优化{int t, j, flag=n, temp;while(flag>0){j=flag;flag=0;for(t=1; t<j; ++t)           //其实冒泡排序每次排都是选出一段区域最大的{if(a[t]<a[t-1]){temp = a[t];a[t] = a[t-1];a[t-1] = temp;flag = t;                }}                               //每次循环结束后flag后面的都是已经排好序了,都比前面大,所以下一次就可以从0-flag排}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}/*63 2 1 2 4 1*/int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}bubbleSort(n);print(n);return 0;}




直接插入排序#include <cstdio>#define N 100using namespace std;int a[N];void insertSort(int n)              //直接插入排序优化{int i, temp, j;for(i=1; i<n; ++i){for(j=i-1; j>=0&&a[j]>a[j+1]; --j)         //每次都把a[i]放入0~(i-1)有序的序列中{temp = a[j];a[j] = a[j+1];a[j+1] = temp;}}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}/*63 2 1 2 4 1*/int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}insertSort(n);print(n);return 0;}



希尔排序#include <cstdio>#define N 100using namespace std;int a[N];//希尔排序,希尔排序在时间效率上比冒泡排序、直接插入排序高void ShellSort1(int n)           {int j, i, gap, k;                 //间隔,同一组中元素间隔for(gap=n/2; gap>0; gap/=2)    {for(i=gap; i<n; ++i){if(a[i]<a[i-gap])       //同一组元素中进行直接插入排序{k = a[i];           //插入a[i]元素进前面的i-gap,i-2*gap,...j = i-gap;while(j>=0&&k<a[j])       //直接插入排序{a[j+gap] = a[j];         j -= gap;}a[j+gap] = k;}}}}void ShellSort2(int n)             //优化后的希尔排序{int j, i, gap, k, temp;for(gap=n/2; gap>0; gap/=2){for(i=gap; i<n; ++i){for(j=i-gap; j>=0&&a[j]>a[j+gap]; j-=gap)       //冒泡排序{temp = a[j+gap];a[j+gap] = a[j];a[j] = temp;}}}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}ShellSort2(n);         print(n);return 0;}



直接选择排序#include <cstdio>#define N 100using namespace std;int a[N];void swap1(int &a, int &b){int temp = a;a = b;b = temp;}void swap2(int &a, int &b){if(a!=b)            //注意异或交换两个元素时要判断,否则a^b=0{a = a^b;b = a^b;a = a^b;}}void SelectSort(int n)                   //直接选择排序{int i, t, minIndex, temp;for(i=0; i<n; ++i){minIndex = i;for(t=i+1; t<n; ++t){if(a[t]<a[minIndex])minIndex = t;}if(minIndex != i)       //交换两个元素{swap2(a[i], a[minIndex]);}}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}SelectSort(n);print(n);return 0;}


归并排序#include <cstdio>#define N 100using namespace std;int a[N];//归并排序的时间复杂度为N*logN,效率是比较高的,比选择、直接插入、冒泡、快排快void mergearray(int l, int mid, int r, int *temp)        //temp数组只是暂时存放数据{int t, i=l, j=mid+1, k=0;while(i<=mid&&j<=r){if(a[i]<a[j])temp[k++] = a[i++];else temp[k++] = a[j++];}while(i<=mid){temp[k++] = a[i++];}while(j<=r){temp[k++] = a[j++];}for(t=0; t<k; ++t){a[l+t] = temp[t];            //更新数组顺序}}void mergesort(int *temp, int l, int r)       //递归分组{int mid;if(r>l){mid = (l+r)>>1;mergesort(temp, l, mid);          //递归   左边有序mergesort(temp, mid+1, r);        //递归   右边有序mergearray(l, mid, r, temp);      //合并   将两个数组合并}}void MergeSort(int n)          //归并排序,先递归分组,然后在合并排序{int *temp = new int[n];mergesort(temp, 0, n-1);delete []temp;}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}MergeSort(n);print(n);return 0;}


快速排序#include <cstdio>#define N 100using namespace std;int a[N];//快速排序,时间复杂度为N*logN,采用挖坑填数(使得所选的基准数左边都是比它小,右边比它大)+分治法(整个数组有序)//在各种排序中是最重要的!!!void QuickSort(int l, int r) {int temp, i=l, j=r;temp = a[l];          //选取最左边的数作为基准数,已它为界,在l的位置挖了个坑if(l<r){while(i<j){while(j>i&&a[j]>=temp)         //从右边开始找小于temp的数{j--;}if(j>i){a[i++] = a[j];            //填补左边坑,右边挖了坑}while(j>i&&a[i]<temp)         //从左边开始找大于temp的数{i++;}if(j>i){a[j--] = a[i];             //填补右边坑,左边完了坑}}a[i] = temp;           //循环一直以来就有一个坑始终未填,最后填上temp,这是i左边都比temp小,右边都比temp大QuickSort(l, i-1);     //分治,左边区间QuickSort(i+1, r);}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}QuickSort(0, n-1);print(n);return 0;}


堆排序#include <cstdio>#include <cmath>#include <iomanip>#define N 100using namespace std;int a[N];//堆排序,建立最大堆,因为输出时数组元素是递增的//堆排序其实是建立一棵完全二叉树void MaxHeapFixDown(int i, int n)      //下沉{int j=i*2, temp=a[i];           //j表示i的左孩子结点while(j<n)                        {if(j+1<n)a[j]>=a[j+1]?j:j++;if(temp>=a[j])              //表示它下面都是符合最大堆的性质,跳出循环break;a[i] = a[j];i = j;j = i*2;}a[i] = temp;}void MakeMaxHeap(int n)          //建立最大堆{int t;          for(t=n/2-1; t>=0; --t)        //先从最后面非叶子结点开始,最后再到根节点(底部有序,才能放根节点)//注意,这里n是不存在的点{MaxHeapFixDown(t, n);   }}void HeapSort(int n)                 //堆排序,升序{for(int t=n-1; t>0; --t){swap(a[t], a[0]);            //最后一个元素与根元素交换MaxHeapFixDown(0, t);        //因为除了根节点,下面的堆都是有序的,每次整个数组都不包括原来与a[t]相换的a[0]}}void print(int n){for(int t=0; t<n; ++t){if(t+1<n)printf("%d ", a[t]);else printf("%d\n", a[t]); }}int main(){int n;scanf("%d", &n);for(int t=0; t<n; ++t){scanf("%d", a+t);}MakeMaxHeap(n);HeapSort(n);print(n);return 0;}/*63 2 1 2 4 1*/


0 0
原创粉丝点击