经典算法之Shell排序及其优化

来源:互联网 发布:易众网络 编辑:程序博客网 时间:2024/06/05 00:56

希尔排序的具体分析见http://blog.csdn.net/morewindows/article/details/6668714/

/************************author's email:wardseptember@gmail.comdate:2017.12.11希尔排序************************/#include<iostream>#define maxSize 10using namespace std;void shellSort1(int *a, int n);void shellSort2(int *a, int n);void Swap(int &a, int &b);//交换函数void shellSort3(int *a, int n);void printArray(int D[], int n);void main() {    int D[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };//构造一个一维数组    int E[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };    int F[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };    shellSort1(D, maxSize);    cout << "希尔排序第一种算法结果为:" << endl;    printArray(D, maxSize);    shellSort2(E, maxSize);    cout << "希尔排序第二种算法结果为:" << endl;    printArray(E, maxSize);    shellSort3(F, maxSize);    cout << "希尔排序第三种算法结果为:" << endl;    printArray(F, maxSize);}void shellSort1(int *a, int n) {    int i, j;    int inc;//代表增量    for(inc=n/2;inc>0;inc/=2)//希尔排序的增量选择都是从n/2开始,每次再减半,直到最后为1        for (i = 0; i < inc; ++i) {//直接插入排序的应用,每一组组内进行排序,可与直接插入排序算法对比理解            for(j=i+inc;j<n;j+=inc)//每次增加inc。用于找到这些元素                if (a[j] < a[j - inc]) {/*在循环刚开始时加上一句判断,若a[j]>=a[i-inc]说明a[0...j]本身就是有序的,无需调整,否则按就调整。*/                    int temp = a[j];                    int k = j - inc;                    while (k >= 0 && a[k] > temp) {//找到要插入的位置,并将a[k+inc]前面的数后移                        a[k + inc] = a[k];                        k -= inc;                    }                    a[k + inc] = temp;//因为最后k减一个temp,所以这里加一个                }        }}/*对比第一种方法可以发现,第二种方法少了一层循环,可以理解为把两个循环合并为一个循环,两种方法都是每组组内进行直接插入排序,遍历完所有元素即可。显而易见,从时间复杂度上来看,第二种方法更简单*/void shellSort2(int *a, int n){    int j, inc;//inc代表增量    for (inc = n / 2; inc > 0; inc /= 2)        for (j = inc; j < n; j++)//从数组第gap个元素开始              if (a[j] < a[j - inc])//每个元素与自己组内的数据进行直接插入排序              {                int temp = a[j];                int k = j - inc;                while (k >= 0 && a[k] > temp)                {                    a[k + inc] = a[k];                    k -= inc;                }                a[k + inc] = temp;            }}void Swap(int &a, int &b) //引用类型方式  {    int temp; //辅助变量      temp = a;    a = b;    b = temp;}/*第三种方法是用元素交换的方法代替数组后移*/void shellSort3(int *a, int n){    int i, j, inc;    for (inc = n / 2; inc > 0; inc /= 2)        for (i = inc; i < n; i++)            for (j = i - inc; j >= 0 && a[j] > a[j + inc]; j -= inc)//将前面两种方法的几句代码,合并为一句。对比理解                Swap(a[j], a[j + inc]);}void printArray(int D[], int n) {    for (int i = 0; i < n; ++i)  //输出排序后的关键字        cout << D[i] << " ";    cout << endl;}

以上如有错误,请指出,大家共同学习进步。

原创粉丝点击