快速排序、归并排序、希尔排序

来源:互联网 发布:李健 知乎 编辑:程序博客网 时间:2024/06/05 02:45

快速排序、归并排序、希尔排序都是采用分治思想的排序。

快速排序:

        可以理解为每一次递归都是把基准元素放到它该在的位置。

        也就是说大于等于此元素的的值都被放在了其右,而小于此元素的值都被放在其左。递归对其左右两边的子数组都进行此操作,直到子数组只有一个元素结束递归。

void QuickSort(char* data,int start,int end){//数组指针,开始下标,结束下标int i, j, k, t;       if (start < end){//数组元素为2个或2个以上才进行操作i = start;j = end + 1;k = data[start];//第一个元素作为基准while (i < j){for (i = i + 1; i < end; i++)if (data[i] >= k)//从第二个元素开始,向后找到第一个不小于基准元素的元素break;for (j = j - 1; j>start; j--)if (data[j] <= k)//从最后一个元素开始,向前找到第一个不大于基准元素的值break;if (i < j){      //i<j说明较之基准,大的元素还在小的元素之左,则交换以上两值,继续while循环t = data[i];data[i] = data[j];data[j] = t;}}//i>=j说明较之基准,大的元素已经完全处在小的元素之右,此时i与j要么相等,要么相差仅为1,说明i,j是基准该在的位置,选其中一个交换元素即可t = data[start];data[start] = data[j];data[j] = t;QuickSort(data,start,j-1);//递归QuickSort(data,j+1,end);}}

归并排序:

对[begin,end)内的元素排序

void MergeSort(char* begin, char* end){int size = end - begin;char *p, *p1, *p2, *mid = begin + size / 2;if (size <= 1) return;MergeSort(begin, mid);//一直递归到子数组大小为1,然后返回MergeSort(mid, end);p = new char[size];//用p来暂时存储排序后的数组        /*两个子数组都已排好序(因为从两个相邻数组只有1个元素开始就进行下列排序),          从两个数组的第一个元素比较,小的先写入p中,并继续拿此数组中下一个元素与另一个数组中第一个元素比较,小的存入p中,          一直到某个子数组全部存入p中,则在吧另一数组中的剩余元素存入p中        */for (p1 = begin, p2 = mid; p1 != mid || p2 != end;)*p++ = (p2 == end || p1 != mid&&*p1 < *p2) ? (*p1++) : (*p2++);for (p -= size; begin != end;){*begin++ = *p++;//写回原数组}p = p - size;delete[] p;}

希尔排序:

      优化的插入排序,对于数组元素,把隔相同步长(代码中gap)的分为一组,进行插入排序,逐渐缩小步长,直到步长为1。

      步长为5的时候,data[0]、data[5]、data[10]等为一组,data[1]、data[6]、data[11]等为一组,依此类推。

void ShellSort(char* data,int num){int i, j, gap,temp;for (gap = num / 2; gap > 0; gap /= 2)    for (i = gap; i < num;i++)//对同一组内元素排序        for (j = i - gap; j >= 0 && data[j] > data[j + gap]; j -= gap){                                /*因为此时[0,j]内改组的元素已经升序排好,要做的就是把j+gap插入合适位置,                                  如果一直小于组内前一个元素,则向前移动,也就是与前一个元素对换,然后继续向前比较*/temp = data[j];data[j] = data[j + gap];data[j + gap] = temp;}}

main.cpp完整代码:

#include<iostream>#include<cstring>using namespace std;void QuickSort(char* data,int start,int end){int i, j, k, t;if (start < end){i = start;j = end + 1;k = data[start];while (i < j){for (i = i + 1; i < end; i++)if (data[i] >= k)break;for (j = j - 1; j>start; j--)if (data[j] <= k)break;if (i < j){t = data[i];data[i] = data[j];data[j] = t;}}t = data[start];data[start] = data[j];data[j] = t;QuickSort(data,start,j-1);QuickSort(data,j+1,end);}}void MergeSort(char* begin, char* end){int size = end - begin;char *p, *p1, *p2, *mid = begin + size / 2;if (size <= 1) return;MergeSort(begin, mid);MergeSort(mid, end);p = new char[size];for (p1 = begin, p2 = mid; p1 != mid || p2 != end;)*p++ = (p2 == end || p1 != mid&&*p1 < *p2) ? (*p1++) : (*p2++);for (p -= size; begin != end;){*begin++ = *p++;}p = p - size;delete[] p;}void ShellSort(char* data,int num){int i, j, gap,temp;for (gap = num / 2; gap > 0; gap /= 2)    for (i = gap; i < num;i++)        for (j = i - gap; j >= 0 && data[j] > data[j + gap]; j -= gap){temp = data[j];data[j] = data[j + gap];data[j + gap] = temp;}}int main(){char data[100];while (1){cin >> data;//QuickSort(data, 0, strlen(data) - 1);//MergeSort(data, data + strlen(data));ShellSort(data, strlen(data));cout << data << endl;}return 0;}


0 0
原创粉丝点击