c++实现数据结构中的各种排序方法:直接插入、选择,归并、冒泡、快速、堆排序、shell排序

来源:互联网 发布:sql primary key 编辑:程序博客网 时间:2024/05/17 23:31
#include "iostream"using namespace std;/*(1) 直接插入排序 (2)(Bonus) 希尔排序(增量为5,2,1) (3) 起泡排序    (4) 快速排序 (5) 直接选择排序 (6)(Bonus) 堆排序 (7)(Bonus)二路归并排序*/void swap(int &a, int &b){    int c = a;    a = b;    b = c;}//冒泡排序的思想:从最后一位开始和前一位比较,如果小于就交换,一直进行下去,每一次都会找到一个最小值,总共要进行n-1步void sort_Bubble(int a[], int len){    for (int i = 0; i < len - 1; i++)     //进行n-1步    {        for (int j = len - 1; j>i; j--)    //从最后一个开始,前i个已经是有序的了,所以不需要在比较了,j>i        {            if (a[j] < a[j - 1])                swap(a[j], a[j - 1]);           //交换        }    }}//直接插入的思想:将紧挨着前面已经排好序的数和前一个比较,如果大于前面一个就不用执行,如果小于前面一个数就要一直和前面的数进行比较,直到找到要插入的位置void sort_insert(int a[], int len)    {        int i, j;        for (i = 1; i < len; i++)   //先假设第一个数已经是有序的了,所以从第二个数开始比较        {            if (a[i] < a[i - 1])    //如果前面一个数小就执行下面的步骤(从小到大排序)            {                int temp = a[i];     //首先将这个数储存起来,以免后面移动会丢失                for (j = i - 1; j >= 0 && a[j]>temp; j--)    //从i-1位开始移动,边移动边判断前面是否还有数比temp大,找到合适的位置插入,结束的标志是j<0||temp>=a[j],就不需要移动了直接插入在j+1的位置                    a[j + 1] = a[j];    //后移                a[j + 1] = temp;   //将temp插入            }        }    }    //选择排序的思想:先假设一个最小值,然后向后比较,如果面有更小的就交换,同时最小值变成这个数再次比较直到一个循环结束,因为最后一个数不用比较,所以要进行n-1步void sort_select(int a[], int len)    {        for (int i = 0; i < len- 1; i++)        {            int min = a[i];     //假设最小值            for (int j = i + 1; j < len; j++)            {                if (min>a[j])                {                    min = a[j];      //改变最小值                    swap(a[i], a[j]);  //交换数                }            }        }    }//这是选择排序的第二种方法:直接用下标来选择void sort_select_1(int a[], int len){    for (int i = 0; i < len - 1; i++)    {        int min = i;   //假设最小值的下标为min        for (int j = i + 1; j<len; j++)        {            if (a[min] > a[j])                min = j;    //记录下标            swap(a[min], a[i]);   //交换数据        }    }}//shell排序:通过增量的方法将一个数组的数据分成若干组,然后在每一个分组中执行直接插入排序,然后减少增量gap,直到增量gap等于1的时候//增量的定义是下标之差,起始是0,然后对应的是下标为0+gap的是一组,继续向后寻找,直到完结(gap<n);/*void sort_shell(int a[], int n){    int i, j, gap,k;    for (gap = n / 2; gap > 0; gap /= 2)    //定义增量gap,起始的增量为n/2,然后减少两倍    {        for (i = 0; i < gap; i++)           //对每一个分组进行排序,0-gap表示每一组中的第一个数的下标,这也是分的组数(gap)        {            for (j = i + gap; j < n; j = j + gap)   //插入排序的思想就是假设第一个已经是有序的,所以就从一组的第二个数开始排序(i+gap)            {                if (a[j] < a[j - gap])    //因为一组中的数据的下标都是相差gap,所以下标为0-gap之间的数都是每一组中的第一个数(没有排序之前)                {                         //下面就是执行直接插入排序                    int temp = a[j];      //将带插入的数据存储                    for (k = j - gap; k >= 0 && temp < a[k]; k = k - gap)   //每一个数据的下标都是相差gap,所以k=k-gap                    {                        a[k + gap] = a[k];                    }                    a[k + gap] = temp;           //插入                }            }        }    }}*///这是对shell排序的每一个分组的排序void group_shell(int a[], int n,int gap){    int j, k;    for (int i = 0; i < gap; i++)    {        for (j = i + gap; j < n; j += gap)        {            if (a[j] < a[j - gap])            {                int temp = a[j];                for (k = j - gap; k >= 0 && temp < a[k]; k = k-gap)                {                    a[k+ gap] = a[k];                }                a[k+ gap] = temp;            }        }    }}//这是调用对数组排序void sort_shell(int a[], int n){    /*    for (int gap = n / 2; gap >0; gap = gap / 2)    {        group_shell(a, n, gap);    }    */    group_shell(a, n, 5);    group_shell(a, n, 3);    group_shell(a, n, 2);    group_shell(a, n, 1);}int main(){    int a[5] = { 22, 33, 4, 11, 77 };//  sort_Bubble(a, 4);//  sort_insert(a, 4);    //sort_select_1(a, 4);    sort_shell(a, 5);    for (int i = 0; i < 5; i++)    {        cout << a[i] << "  ";    }    return 0;}

//等待后面还会陆续更新新的排序方式,这里只是更新了几种,希望大家一起学习

0 0
原创粉丝点击