排序算法总结

#include <iostream> 
#include <list>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <map>
#include <functional>
#include <algorithm>
#include <stack>
#include <ctime>
using namespace std;
//冒泡排序(n2)
//相邻元素交换,未交换结束,每次减1
void buble_sort(int a[], int n)
{
    bool flag;
    do
    {
        flag = false;
        for (int j = 1; j < n; j++)
        {
            if (a[j - 1]>a[j])
            {
                swap(a[j], a[j - 1]);
                flag = true;
            }
        }
        n--;
    } while (flag);

}
//插入排序,有序序列和无序序列,o(n*2),稳定
//从1开始依次和前面的有序序列相比,找到合适的插入位置插入
void insert_sort(int a[], int n)
{
    int t,i,j;
    for (i = 1; i < n;i++)
    {
        t = a[i];//要插入的位置
        for (j = i; j>0&&a[j-1]>t;j--)
        {
            a[j] = a[j - 1];
        }
        a[j] = t;
    }
}
//选择排序,选择最小(不稳定) ,o(n*2)
//3 7 4 2
void select_sort(int a[], int n)
{
    for (int i = 0; i < n;i++)
    {
        int min = i;
        for (int j = i + 1; j < n; j++)
        {
            if (a[j] < a[min]) min = j;
        }
        if (min != i) swap(a[i],a[min]);
    }

}
//快速排序思路,找分界值,一般用中间得数据作为分界值,和第一个元素交换作为界,O (nlogn)
//分组,比分界值小的在一边,比分界值大的在一边
    //1.从左向右找,比分界值大的停下(避免走出右边界)
    //2.从右向左找,比分界值小的停下(避免走出左边界)
    //3, 交换
//如果分界值比,左右相遇的的值大,交换
//递归左边分组
//递归右边分组
//递归结束条件,元素个数不超过一个
void quick_sort(int a[], int n)
{
    if (n <= 1) return;
    if (n == 2) {
        swap(a[0], a[1]); return;
    }
    swap(a[n / 2], a[0]);
    int jie = a[0];
    int* L = a + 1;
    int* R = a + n - 1;
    while (L<R)
    {
        while (L < R&&*L < jie) L++;
        while (a<R&&*R>=jie) R--;
        if (L < R) swap(*L,*R);
    }
    if (*R<jie)
    {
        swap(a[0], *R);
    }
    quick_sort(a,R-a);
    quick_sort(R + 1, (n - 1) - (R - a));
        
}

/**************************** 排序规则 ****************************

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰
被分成一组,算法便终止。

稳定性: 希尔排序是非稳定排序算法。

*****************************************************************/
//希尔排序O(n^(1.3—2))
void shellSort(int *array, int len)
{
    // 步长
    int gap = len;
    while (gap > 1)
    {
        // 步长递减公式
        gap = gap / 3 + 1;
        // 分组, 对每一组, 进行插入排序
        for (int i = 0; i < gap; ++i)
        {
            int tmp;    // 基准数
            int index;    // 坑的位置
            // 插入排序
            // 无序序列
            for (int j = i + gap; j < len; j += gap)
            {
                tmp = array[j];
                index = j;
                // 有序序列(从后往前遍历)
                for (int k = j - gap; k >= 0; k -= gap)
                {
                    if (tmp < array[k])
                    {
                        // 后移
                        array[k + gap] = array[k];
                        // 位置
                        index = k;
                    }
                    else
                    {
                        break;
                    }
                }
                // 填坑
                array[index] = tmp;
            }
        }
    }
}


//分组加插入排序
void shell_sort2(int a[],int n)
{
    int gap = n,k=0,i=0,j=0;
    while (gap>1)
    {
        gap= gap / 3 + 1;
        
        for ( i = 0; i < gap;i++)
        {
            for (j = i+gap; j < n;j+=gap)
            {
                int t = a[j];
                for ( k = j ; k > 0&&a[k-gap]>t;k-=gap)
                {
                    a[k] = a[k - gap];
                }
                a[k] = t;
            }
        }
    }
        
}
//归并排序o(nlogn),稳定
//将两个有序数列a[first...mid]和a[mid+1...last]合并。
void mergeArray(int a[], int first, int mid, int last, int temp[])
{
    int i = first;    // 第一个有序序列的开始下标
    int j = mid + 1;    // 第2个有序序列的开始下标

    int length = 0;
    // 合并两个有序序列
    while (i <= mid && j <= last)
    {
        // 找二者中比较小的数
        if (a[i] < a[j])
        {
            temp[length] = a[i];
            i++;
        }
        else
        {
            temp[length] = a[j];
            j++;
        }
        length++;
    }
    // 还剩下一个有序序列中有数据
    while (i <= mid)
    {
        temp[length] = a[i];
        i++;
        length++;
    }
    while (j <= last)
    {
        temp[length++] = a[j++];
    }

    // 覆盖原来位置的无序序列
    for (int i = 0; i < length; ++i)
    {
        // 找到原来 的第一个有序序列的开始位置 - 开始覆盖
        a[first + i] = temp[i];
    }
}

//归并排序
void mergeSort(int a[], int first, int last, int temp[])
{
    // 递归结束的条件
    if (first == last)
    {
        return;
    }
    // 从中间位置拆分
    int mid = (first + last) / 2;
    // 拆分
    // 左半边
    mergeSort(a, first, mid, temp);
    // 右半边
    mergeSort(a, mid + 1, last, temp);
    // 合并两个有序序列
    mergeArray(a, first, mid, last, temp);
}


#define  N 65530

int main()
{
    int a[N];
    
    for (int i = N; i > 0;i--)
    {
        a[N - i] = i;
    }
    int*p = (int*)malloc(sizeof(int)*N);
    clock_t t1 = clock();
    mergy_sort2(a, 0,N-1,p);
    clock_t t2 = clock();
    cout << "time:"<<double(t1 - t2) / CLOCKS_PER_SEC << endl;
    for (int i = 0; i < 10;i++)
    {
        cout << a[i] << " ";
    }
    cout << endl;
    free(p);
    system("pause");
}

 

posted @ 2019-08-27 20:42  白伟碧一些小心得  阅读(428)  评论(0编辑  收藏  举报