排序

快速排序:

基本思想:

1.选定一个合适的值(理想情况中值最好,但实现中一般使用数组第一个值),称为“枢轴”(pivot)。

2.基于这个值,将数组分为两部分,较小的分在左边,较大的分在右边。

3.可以肯定,如此一轮下来,这个枢轴的位置一定在最终位置上。

4.对两个子数组分别重复上述过程,直到每个数组只有一个元素。

5.排序完成。

void mysort(int a[], int low, int high)
{
    int i=low;
    int j=high;
    if (i < j)
    {
        int temp = a[low];
        while(i < j)
        {
            while(a[j]>=temp && i<j)
                j--;
            a[i] = a[j];
            while (a[i]<=temp && i<j)
                i++;
            a[j] = a[i];
        }
        a[i] = temp;
        mysort(a, low, i-1);
        mysort(a, i+1, high);
    }
}

 冒泡排序

基本思想是:比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

void mysort(int a[], int n)
{
    for (int i=0; i<n; i++)
    {
        for (int j=0; j<n-1-i; j++)
        {
            if (a[j] > a[j+1])
                std::swap(a[j], a[j+1]);
        }
    }
}

 直接插入排序:

基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

void mysort(int a[], int n)
{
    for (int i=1; i<n; i++)
    {
        int j;
        int temp = a[i];
        for (j=i-1; j>=0; j--)
        {
            if (a[j] < temp)
                break;
        }
        for (int k=i-1; k>j; k--)
        {
            a[k+1] = a[k];
        }
        a[j+1] = temp;
    }
}

 折半插入排序:

基本思想:

折半插入排序的基本思想与直接插入排序一样,在插入第i(i1)i(i≥1)个元素时,前面i1i−1个元素已经排好序。区别在于寻找插入位置的方法不同,折半插入排序是采用折半查找法来寻找插入位置的。 
折半查找法的基本思路是:用待插元素的值与当前查找序列的中间元素的值进行比较,以当前查找序列的中间元素为分界,确定待插元素是在当前查找序列的左边还是右边,如果是在其左边,则以该左边序列为当前查找序列,右边也类似。按照上述方法,递归地处理新序列,直到当前查找序列的长度小于1时查找过程结束。

void mysort(int a[], int n)
{
    int low,high, mid;
    for (int i=1; i<n; i++)
    {
        int temp = a[i];
        low = 0;
        high = i-1;
        while(low <= high)
        {
            mid = (low+high)/2;
            if (a[mid] < temp)
                low = mid+1;
            else
                high = mid-1;
        }
        for (int j=i-1; j>high; j--)//最后一次判断决定是插入在low==higi时这个数之前还是之后
        {
            a[j+1] = a[j];
        }
        a[high+1] = temp;
    }
}

 希尔排序:

基本思想:

先比较距离远的元素,而不是像简单交换排序算法那样先比较相邻的元素,这样可以快速减少大量的无序情况,从而减轻后续的工作。被比较的元素之间的距离逐步减少,直到减少为1,这时的排序变成了相邻元素的互换。

void mysort(int a[], int n)
{
    int gap = n;
    while ((gap /= 2) > 0)
    {
        for (int i=gap; i<n; i++)
        {
            int temp = a[i];
            int j;
            for (j=i-gap; j>=0; j-=gap)
            {
                if (a[j] > a[j+gap])
                    std::swap(a[j], a[j+gap]);
            }
        }
    }
}

 堆排序:

基本思想:

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

void make_max_heap(int a[], int begin, int end)
{
    int father = begin;
    int son = 2*father+1;
    while(son < end)//子节点有效才进行比较
    {
        if (son+1<end && a[son]<a[son+1])//去两个子节点中较大的字节进行比较
            son++;
        if (a[son] > a[father])//判断子节点是否大于父节点,是则交换
        {
            std::swap(a[son], a[father]);
            father = son;
            son = father*2+1;
        }
        else//父节点比两个子节点都大不用交换
        {
            return;
        }
    }
}

void mysort(int a[], int n)
{
    for (int i=n/2-1; i>=0; i--)//初始化大顶堆
    {
        make_max_heap(a, i, n);
    }
    for (int i=n-1; i>0; i--)//将堆顶元素与堆尾元素交换,除了堆尾元素其余的再次构建大顶堆
    {
        std::swap(a[0], a[i]);
        make_max_heap(a, 0, i);//除了堆顶其余的都保持大顶堆关系,所以从0开始就行,不用像初始化一样从底向上循环
    }
}

 归并排序:

基本思想:

基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?

可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。

void merge_array(int a[], int first, int mid, int last, int temp[])
{
    int i=first, j=mid+1;
    int n=mid, m=last;
    int k=0;
    while (i<=n && j<=m)
    {
        if (a[i] < a[j])
        {
            temp[k++] = a[i++];
        }
        else
        {
            temp[k++] = a[j++];
        }
    }
    while (i<=n)
    {
        temp[k++] = a[i++];
    }
    while (j<=m)
    {
        temp[k++] = a[j++];
    }
    for (i=0; i<k; i++)
    {
        a[first+i] = temp[i];
    }
}

void merge_sort(int a[], int start, int end, int temp[])
{
    if (start < end)
    {
        int mid = (start + end) / 2;
        merge_sort(a, start, mid, temp);
        merge_sort(a, mid+1, end, temp);
        merge_array(a, start, mid, end, temp);
    }
}

void mysort(int a[], int n)
{
    int *p = new int[n];
    if (NULL == p)
        return;
    merge_sort(a, 0, n-1, p);
    delete[] p;
}

 

posted on 2018-03-24 16:29  GnibChen  阅读(160)  评论(0编辑  收藏  举报