希尔排序基本思想

先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2
=1(
<
该方法实质上是一种分组插入方法
比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比 [2]  较就可能消除多个元素交换。D.L.shell于1959年在以他名字命名的排序算法中实现了这一思想。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
一般的初次取序列的一半为增量,以后每次减半,直到增量为1。
给定实例的shell排序的排序过程
假设待排序文件有10个记录,其关键字分别是:
49,38,65,97,76,13,27,49,55,04。
增量序列的取值依次为:
5,3,1  
 
#include 
using namespace std;
// 希尔排序( update insert_sort)
const int maxn = 1010;
int num[maxn];
void shell_sort(int *data,unsigned int len)
{
    if(len<=1||data==NULL)
       return;
    for(int div=len/2;div>=1;div=div/2)//定增量div,并不断减小
   {
        for(int i=0;i<=div;++i)        //分组成div组
        {
         for(int j=i;j//对每组进行插入排序
         for(int k=j;kdiv)
         if(data[j]>data[k])
         swap(*(data+j),*(data+k));       //交换两个数的值
        }
    }
}
int main()
{
    int x;
    scanf("%d",&x);
    for(int i=0;i)
        scanf("%d",&num[i]);
    shell_sort(num,x);
    for(int i=0;i)
        printf("%d%c",num[i],i==x-1?'\n':' ');
    return 0;
}
Shell

 

 

 


 

 归并排序:

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

分为自然归并和递归归并,都写在了代码里,自然归并过程就是注释;

数据结构 重点详解_第13张图片

 

 

 
#include 
using namespace std;
// 归并排序
const int maxn = 1010;
int num[maxn];
/*
void merge_sort(int arr[], int len) {
    int* a = arr;
    int* b = (int*) malloc(len * sizeof(int));
    int seg, start;
    for (seg = 1; seg < len; seg += seg) {
        for (start = 0; start < len; start += seg + seg) {
            int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
            int k = low;
            int start1 = low, end1 = mid;
            int start2 = mid, end2 = high;
            while (start1 < end1 && start2 < end2)
                b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
            while (start1 < end1)
                b[k++] = a[start1++];
            while (start2 < end2)
                b[k++] = a[start2++];
        }
        int* temp = a;
        a = b;
        b = temp;
    }
    if (a != arr) {
        int i;
        for (i = 0; i < len; i++)
            b[i] = a[i];
        b = a;
    }
} // 自然归并
*/
void merge(int a[], int first, int mid, int last)
{
    int i = first, j = mid + 1;
    int m = mid,   n = last;
    int k = 0;
    int l=mid-first;
    int temp[maxn];
    while (i <= m && j <= n)
    {
        if (a[i] <= a[j])
            temp[k++] = a[i++];
        else
        {
            temp[k++] = a[j++];
        }

    }

    while (i <= m)
        temp[k++] = a[i++];

    while (j <= n)
        temp[k++] = a[j++];

    for (i = 0; i < k; i++)
        a[first + i] = temp[i];
}
void mergesort(int a[], int first, int last)
{
    if (first < last)
    {
        int mid = (first + last) / 2;
        mergesort(a, first, mid);    //左边有序
        mergesort(a, mid+1, last); //右边有序
        merge(a, first, mid, last); //再将二个有序数列合并
    }
}
int main()
{
    int x;
    scanf("%d",&x);
    for(int i=1;i<=x;i++)
        scanf("%d",&num[i]);
    mergesort(num,1,x);
    for(int i=1;i<=x;i++)
        printf("%d%c",num[i],i==x?'\n':' ');
    return 0;
}
/*
7
5 8 9 2 3 1 10
*/
归并

 


基数排序: 

数据结构 重点详解_第14张图片

 

  非重点,选择了解,可以百度理解下再来看代码

(不是我太懒了 , 逃)、

#include 
using namespace std;
// 基数排序
const int maxn = 1010;
int num[maxn];
int maxbit(int *a,int n)
{
    int ans = *max_element(a,a+n);
    int len = 0;
    while(ans)
    {
        len++;
        ans/=10;
    }
    return len;
    /*
    int d = 1; //保存最大的位数
    int p = 10;
    for(int i = 0; i < n; ++i)
    {
        while(a[i] >= p)
        {
            p *= 10;
            ++d;
        }
    }
    return d;
    */
}
void bin_sort(int *a,int n)
{
    int d = maxbit(a,n);
    int tmp[maxn];
    int counts[maxn];
    int i,j,k;
    int radix = 1;
     for(i = 1; i <= d; i++) //进行d次排序
    {
        memset(counts,0,sizeof(counts));//clear array
        for(j = 0; j < n; j++)
        {
            k = (a[j] / radix) % 10; //统计每个桶中的记录数
            counts[k]++;
        }
        for(j = 1; j < 10; j++)
            counts[j] = counts[j - 1] + counts[j]; //将tmp中的位置依次分配给每个桶
        for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
        {
            k = (a[j] / radix) % 10;
            tmp[counts[k] - 1] = a[j];
            counts[k]--;
        }
        for(j = 0; j < n; j++) //将临时数组的内容复制到a中
            a[j] = tmp[j];
        radix = radix * 10;
    }
}
int main()
{
    int x;
    scanf("%d",&x);
    for(int i=0;i)
        scanf("%d",&num[i]);
    bin_sort(num,x);
    for(int i=0;i)
        printf("%d%c",num[i],i==x-1?'\n':' ');
    return 0;
}
/*
7
5 8 9 2 3 1 10
*/
base sort

 

 


 

堆排序:           推荐:https://www.cnblogs.com/chengxiao/p/6129630.html

在介绍堆排序之前,首先需要说明一下,堆是个什么玩意儿。

是一棵顺序存储完全二叉树

其中每个结点的关键字都不大于其孩子结点的关键字,这样的堆称为小根堆

其中每个结点的关键字都不小于其孩子结点的关键字,这样的堆称为大根堆

举例来说,对于n个元素的序列{R0, R1, ... , Rn}当且仅当满足下列关系之一时,称之为堆:

(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)

(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)

其中i=1,2,…,n/2向下取整; 

// TODO......

#include 
using namespace std;
// 堆排序
const int maxn = 1010;
int num[maxn];
void HeapAdjust(int *a,int i,int n)  //调整堆
{
    int lchild=2*i;       //i的左孩子节点序号
    int rchild=2*i+1;     //i的右孩子节点序号
    int ipos=i;            //临时变量
    if(i<=n/2)          //如果i不是叶节点就不用进行调整
    {
        if(lchild<=n&&a[lchild]>a[ipos])
        {
            ipos=lchild;
        }
        if(rchild<=n&&a[rchild]>a[ipos])
        {
            ipos=rchild;
        }
        if(ipos!=i)
        {
            swap(a[i],a[ipos]);
            HeapAdjust(a,ipos,n);    //避免调整之后以max为父节点的子树不是堆
        }
    }
}

void BuildHeap(int *a,int n)    //建立堆
{
    int i;
    for(i=n/2;i>=1;i--)    //非叶节点最大序号值为size/2
    {
        HeapAdjust(a,i,n);
    }
}

void HeapSort(int *a,int n)    //堆排序
{
    int i;
    BuildHeap(a,n);
    for(i=n;i>=1;i--)
    {
        swap(a[1],a[i]);           //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
        HeapAdjust(a,1,i-1);      //重新调整堆顶节点成为大顶堆
    }
}
int main()
{
    int x;
    scanf("%d",&x);
    for(int i=1;i<=x;i++)
        scanf("%d",&num[i]);
    HeapSort(num,x);
    for(int i=1;i<=x;i++)
        printf("%d%c",num[i],i==x?'\n':' ');
    return 0;
}
/*
7
5 8 9 2 3 1 10
*/
堆排序

 

 


 

写在最后:

    实在抱歉,暂时只能想起来的基础部分只有这么多了,还有许多详细的内容没有填充上去,如果您有好的建议,希望不吝赐教,请尽管在评论区发表,或者私信给我,附加上您希望添加的内容,希望能在各位斧正下尽快完善了这个文章。

    有许多部分的内容会对于初学者来说会有那么一点不好理解,如果可能的话,希望初学者在查阅并且学习的过程中,能够整理下来自己存在理解障碍的地方或者自己想要完善的部分,尽可能利用百度。谷歌等工具理解这些内容,最后如果有可能的话,能将你们整理的适合添加的内容分享给我一部分,最好能指出希望修改的部分,我的邮箱   [email protected]

        还有,希望大家能给个关注,谢谢各位。 

 

 我的博客即将同步至腾讯云+社区,邀请大家一同入驻。