七大排序总结

大四狗刚考完研,刷牛客网的时候发现自己七大排序都不能很流畅地写出来,实在惭愧,而排序算法是非常基础和重要的算法,所以今天特意总结了下排序算法。
为了编码方便,我所有的排序都是递增排序
(算法解释我就不写了,好多博主写了解释,感觉学会以后写算法解释好费时间。。。。每个排序我都会贴几个解释得比较好的博客链接,文末我会贴上我对这个七个排序所有的源代码,代码都写得比较精简,不过要是有觉得我写得不好的可以给我留言,毕竟我没有找别人看过代码)
一:冒泡排序
二:插入排序
三:简单选择排序
四:归并排序
五:堆排序
六:希尔排序
七:快速排序
为什么不自己写这些排序算法呢。。。?因为我懒。。我只是知识的搬运工orz。
上一段我写的完整代码,很长奥,耐着性子看完,会有收获的!(C++、Visual Studio 2017)

#include<iostream>
#include<string>
using namespace std;
//所有排序算法,为了方便都从小到大来实现
template<class T>
void swap(T*num, int i, int j)//交换元素
{
    T tmp; 
    tmp=num[i];
    num[i] = num[j];
    num[j] = tmp;
}
//冒泡排序, 时间复杂度O(n ^ 2),空间复杂度O(1);
template<class T>
void BubbleSort(T *num, int size)
{
    if (size <= 1)return;
    for (int i = 0; i < size; i++)
    {
        bool flag = false;
        for (int j = 0; j < size - i - 1; j++)
            if (num[j] > num[j + 1])
            {
                swap(num, j, j + 1);
                flag = true;
            }
        if (!flag)return;//这个是个好改进,排序完成了就退出

    }
}
//插入排序,时间复杂度O(n^2),空间复杂度O(1)
template<class T>
void InsertSort(T*num, int size)
{
    if (size <= 1)return;
    for (int i = 1; i < size; i++)
    {
        T tmp = num[i];
        int j;
        for (j = i - 1; j >= 0 && tmp < num[j]; j--)
        //反正我觉得这个写法挺酷炫的哈哈
            num[j + 1] = num[j];
        num[j + 1] = tmp;
    }
}
//简单选择排序,时间复杂度O(n^2),空间复杂度O(1)
template<class T>
void SelectSort(T*num, int size)
{
    if (size <= 1)return;
    for (int i = 0; i < size; i++)
    {
        int min = num[i];
        int min_dex = i;
        for (int j = i + 1; j < size; j++)
        {
            if (num[j] < min)
            {
                min = num[j];
                min_dex = j;
            }
            swap(num, min_dex, i);
        }
    }
}
//快速排序,时间复杂度O(logN),空间复杂度O(logN);
template<class T>
void QuickSort(T*num, int size)
{
    int start = 0;
    QuickSortway(num, start, size - 1);
    之所以另外弄个函数,我只是想QuickSort函数和其他排序的参量一致
}
template<class T>
void QuickSortway(T*num, int s, int t)//递归求解
{
    T tmp = num[s];
    int i = s;
    int j = t;
    if (s >= t)return;
    while (i < j)
    {
        //这样写快排,背都能背下来了
        while (i<j&&num[j]>tmp)j--;
        num[i] = num[j];
        while (i<j&&num[i]<tmp)i++;
        num[j] = num[i];
    }
    num[i] = tmp;
    QuickSortway(num, s, i - 1);
    QuickSortway(num, i + 1, t);

}
//堆排序,时间复杂度O(logN),空间复杂度O(1)
/*堆排序略微难理解,值得注意的是,我们要从小到大排序,是要建成大顶堆,这一点都不矛盾,因为建成大堆之后我们将堆顶和堆尾交换,这样最后一个元素就是最大的,然后再调整堆,如此循环,我一开始是就是这里卡了,不过你要是建立小顶堆也可以,就是不断地把堆顶取出来,用尾元素替换,取出来的值放到新的数组中,但是这样要开辟新的空间*/
template<class T>
void HeapAdjust(T*num, int i, int size)//调整堆,大顶堆
{
    int child = 2 * i + 1;//左孩子节点下标
    while (child<size)
    {
        if (child + 1 < size&&num[child]<num[child + 1])//右孩子更小
            child++;
        if (num[child]>num[i])
        {
            swap(num, child, i);
            i = child;
            child = 2 * i + 1;
        }
        else
            break;
    }
}
template<class T>
void HeapSort(T*num, int size)//堆排序
{
    if (size <= 1)return;
    for (int i = size / 2 - 1; i >= 0; i--)
    {
        HeapAdjust(num, i, size);
    }//构建初始堆
    for(int i = size - 1; i > 0; i--)
    {
        swap(num, 0, i);
        HeapAdjust(num, 0, i);//不断地把堆顶取下来放到末尾
    }
}
//定义的输出函数
template<class T>
void printout(T*num,int size)
{
    for (int i = 0; i < size; i++)
        cout << num[i];
    cout << endl;
}
//归并排序,时间复杂度O(logN),空间复杂度O(N)因为需要另外开个数组
template<class T>
void MergeSort(T*num, int size)
{
    if (size <= 1)return;
    MergeSortway(num, 0, size - 1);
}
template<class T>
void MergeSortway(T*num, int begin, int end)
{
    if (begin < end)
    {
        int mid = (begin + end) / 2;
        MergeSortway(num, begin, mid);
        MergeSortway(num, mid + 1, end);
        Merge(num, begin, mid,end);
    }
}
template<class T>
void Merge(T*array, int low, int mid, int hight) {
    if (low >= hight) {
        return;
    }
    T*auxArray = new T[hight - low + 1];
    int index1 = low;
    int index2 = mid + 1;
    int i = 0;
    while (index1 <= mid && index2 <= hight) {
/*虽然这样可读性低,但是我觉得很酷啊,哈哈哈,理解下++的前缀后缀就懂了*/
        if (array[index1] <= array[index2]) 
            auxArray[i++] = array[index1++];
        else 
            auxArray[i++] = array[index2++];
    }
    // 继续合并前半段数组中未被合并的部分
    while (index1 <= mid) 
        auxArray[i++] = array[index1++];
    // 继续合并后半段数组中未被合并的部分
    while (index2 <= hight) 
        auxArray[i++] = array[index2++];
    // 将合并好的序列写回到数组中
    for (int j = 0; j < hight - low + 1; j++) 
        array[low + j] = auxArray[j];
    delete[]auxArray;

}
template<class T>
void initial(T*t,int size)
{
    t[0] = 2;
    t[1] = 3;
    t[2] = 4;
    t[3] = 1;
    t[4] = 5;
    t[5] = 9;
    t[6] = 8;
    t[7] = 7;
    t[8] = 6;
    t[9] = 0;
}
//希尔排序,这个时间复杂度和div大小有关,不好分析,空间复杂度O(1)
template<class T>
void ShellSort(T num[], int size)
{
    T gap, i, j;
    for (gap = size / 2; gap > 0; gap /= 2)
        for (i = gap; i < size; i++)
            for (j = i - gap; j >= 0 && num[j] > num[j + gap]; j -= gap)
                swap(num, j, j + gap);
}
int main()
{
    int num[10] = { 2,3,4,1,5,9,8,7,6,0 };
    cout << "冒泡排序结果" << endl;
    BubbleSort(num, 10);
    printout(num, 10);
    cout << endl << "选择排序结果" << endl;
    initial(num, 10);
    SelectSort(num, 10);
    printout(num, 10);
    cout << endl << "插入排序结果" << endl;
    initial(num, 10);
    InsertSort(num, 10);
    printout(num, 10);
    cout << endl<< "堆排序结果" << endl;
    initial(num, 10);
    HeapSort(num, 10);
    printout(num, 10);
    cout << endl << "快速排序结果" << endl;
    initial(num, 10);
    QuickSort(num, 10);
    printout(num, 10);
    cout << endl << "归并排序结果" << endl;
    initial(num, 10);
    MergeSort(num, 10);
    printout(num, 10);
    cout << endl << "希尔排序结果" << endl;
    initial(num, 10);
    ShellSort(num, 10);
    printout(num, 10);
    getchar();
    return 0;
}

2018,请对自己狠一点!!!未来会更好,不放弃!

猜你喜欢

转载自blog.csdn.net/kellen_f/article/details/79029066