各种排序的C语言实现

来源:互联网 发布:京东和淘宝有什么区别 编辑:程序博客网 时间:2024/05/07 23:55

归并排序

归并排序的思想就是将一个数组分为二组,如果这两组数组是有序的话,那么可以很快将这两组数组进行排序。

那么怎么样才能让这两个数组内的数据都有序呢?

可以通过递归的方法,将两个数组各自再分为两组,以此类推,当每个组都只有一个数据的时候,可以认为有序。

再合并数组。

总结起来:归并排序就是通过递归对数组进行分解,再通过合并,从而完成归并排序。

#include <cstdio>void mergeArray(int* array, int first, int mid, int last, int* buff){    int i, j, m, n,k;    i = first;    j = mid;    m = mid+1;    n = last;    k = 0;    while (i <=j&&m <=n)    {        if (array[i] <=array[m])            buff[k++] = array[i++];        else            buff[k++] = array[m++];    }    while (i <= j)//如果其中一个数组已经全部移动到buff中,则把另一个数组剩余的元素按序移动到buff。    {        buff[k++] = array[i++];    }    while (m <= n)//如果其中一个数组已经全部移动到buff中,则把另一个数组剩余的元素按序移动到buff。    {        buff[k++] = array[m++];    }    for (int q = 0; q < k; q++)    {        array[first + q] = buff[q];//两组数组归并好后替换掉原有的数组    }}void mergeSort(int* array, int first,int last,int* buff){    if (first < last)    {        int mid = (first + last) / 2;        mergeSort(array, first, mid, buff);        mergeSort(array, mid + 1, last, buff);        mergeArray(array, first, mid, last, buff);    }}bool MergeSort(int* array, int n){    int* buff = new int[n];//开辟一个临时空间    if (!buff)        return false;    mergeSort(array, 0, n-1, buff);    delete[] buff;//要记得释放    return true;}

希尔排序

希尔排序的基本思想是分组插入排序。

基本步骤就是:将整个数组分为若干个子序列,每个子序列的数据相隔某一增量,分别对每个子序列进行直接插入排序。

完成后,再缩小增量,对整个数组进行子序列的重新划分。再对每个子序列进行直接插入排序,以此类推。

直到每个子序列都只有一个单独的数据,最后进行一次直播插入排序。

void shellSort(int* array, int n){    for (int gap = n / 2; gap >0; gap /= 2)    {        for (int i = gap; i < n; i++)        {            for (int j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap)            {                swap(array[j], array[j + gap]);            }        }    }}

直接插入排序

void insertSort(int* array,int n){    for (int i=1 ; i < n; i++)    {        for (int j = i - 1; j >= 0 && array[j] > array[j+1]; j--)        {            swap(array[j], array[j + 1]);        }    }}

快速排序

快速排序的主要思想:
【1】选取一个基准,进行分区。将小于基准的数放在基准的左边,将大于基准的数放在基准的右边。对此序列以基准为基准,左边全部是小于基准的数,右边全部是大于基准的数。
【2】运用递归的思想再分别对左右两个半区进行再快速排序。

快速排序的举例说明:

如取array[]={4,7,8,3,6}进行简单说明

【1】取4为基准,i=0, j=4,i用于向右找比4大的数,j用于向左找比4小的数。
【2】首先,先向左找比基准4小的数,6?不是,3?比4小!!此时把基准挖一个坑,并把3填入4的位置,此时基准的坑被填好了,但却出现了一个新的坑,即原来3所在的位置。将值array[0 ]=array[3]后,j–;
【3】接下来,从左向右找一个比基准4大的数,并填入新的坑。7?比4大。好,那么将7这个数值填入新的坑中。array[3]=array[2] ;i++;
【4】当i=j或者是i>j时,停止寻找。
【5】并将基准填入最后出现的坑中。
【6】经历了以上6个步骤后,数组变为3 4 8 7 6 。发现,基准4的左边全是小于4的数,右边全是大于4的数。即成功地进行分区!!
【7】再接下来,运用递归的思想分别再对左右两边进行同样的操作。

//快速排序函数void quickSort(int* array, int arrayBegin, int arrayEnd){    if (arrayBegin < arrayEnd)//确保输入的参数有效,同时也是递归终止的关键    {        int i = arrayBegin;        int j = arrayEnd;        int base = array[arrayBegin];//以目标序列的第一个数为基准        while (i < j)//i=j或者i>j后都不再进行分区        {            while ((i < j) && (array[j] >= base))//从后往前找直到找到比基准小的数                j--;            if (i < j)                array[i++] = array[j];//要注意到是先把array[j]赋给array[i]后,i才自加的。此时把坑array[i]填了后,array[j]变成了坑。            while ((i<j) && (array[i]< base))//while里条件重复一下i<j是有必要的,因为上面的程序会进行 i,j的运算。以防上面的程序运行完后i=j,或者i>j了!!                i++;            if (i < j)                array[j--] = array[i];//要注意到是先把array[i]赋给array[j]后,j才自加的。此时把坑array[j]填了后,array[i]变成了坑。        }        array[i] = base;//到最后留下的坑由基准来填。        quickSort(array, arrayBegin, i - 1);//递归调用对左半区再进行排序        quickSort(array, i + 1, arrayEnd);//递归调用对右半区再进行排序    }}

冒泡排序

//原理版冒泡排序void bubbleSort1(int array[],int n){    for (int i = 0; i < n; i++)    {        for (int j = 0; j < n - i-1; j++)        {            if (array[j] > array[j+1])            {                swap(array[j], array[j+1]);            }        }    }}//优化版冒泡排序void bubbleSort4(int array[], int n){    int numCount = n;    while (numCount>0)    {        int k = numCount;        numCount=0;//如果没有可交换的数,这句的作用就可以使while循环结束。        for (int j = 0; j < k - 1; j++)//比如数组有5个数,则第遍历一次要4次         {            if (array[j] > array[j + 1])            {                swap(array[j], array[j + 1]);                //记录下此时交换数组的位置                //优点:比如说100个数,后90个数都是排序好的                //那么,第一次进行交换的位置j一定在10以内                //记录后赋给一个标志位,从此标志位之后不用再去遍历,而是遍历前10位                //通俗来说,因为后90个已经不再须要排序,我们可以把这个数组当成只有前10位                numCount = j + 1;//为什么+1具体逻辑可能得自己通过特殊取值法来验算            }        }    }}
//测试主函数void main(){    int a[] = { 8,7,10,1,3,5,4,9 };    quickSort(a, 0, 7);    bubbleSort4(a,8);    for (int i = 0; i < 8; i++)        printf("%d  ", a[i]);}
2 0
原创粉丝点击