这些年写过的排序算法

/*Author: LJM
 *    CSDN: TT_LJM
 *    QQ: 1151473641
 */

#include <iostream>
#include <stack>
#include <time.h>
using namespace std;

/*O(n*n)时间复杂度*/
void BubbleSort(T *sort, int size);                    /*冒泡排序*/
void BubbleSort2(T *sort, int size);                /*冒泡排序改进版*/
void SelectSort(T *array, int size);                /*选择排序*/

void InsertSort(T *array, int size);                /*插入排序*/

/*O(nlogn)时间复杂度*/

void ShellSort(T *array, int size);                    /*希尔排序*/
void QuickSort(T *array, int first, int last);        /*快速排序*/
void QuickSortByNonrecursive(T *array, int first, int last);            /*快速排序非递归*/
void MergeSortByRecursive(T *array, int first, int last, T *container); /*归并排序(递归)*/
void HeapSort(T *array, int size);                    /*堆排序*/

void MergeSort(T *array, int size, T *container);    /*归并排序*/


void recursive_merge_sort(ListNode<T> *&listhead);    /*链表的归并排序*/

/*线性时间复杂度的排序算法(还有桶排序,实现基本跟基数排序差不多,这里不贴代码了)*/
void CountSort(T *array, int size);                    /*计数排序*/
void radix_sort(int *array, int size);                /*基数排序*/


/*稳定的排序算法有:归并排序,基数,计数,冒泡,插入,*/


/*不常见的排序算法*/
void ShakerSort(T *array, int size);                /*鸡尾酒排序(也就是双向冒泡)*/
void odd_even_sort(T *array, int size)                /*奇偶排序(多处理器下效率高)*/





template <class T>
void Swap(T &a, T &b)
{
    T temp = a;
    a = b;
    b = temp;
}

/*冒泡排序, 时间复杂度O(n*n)*/
template <class T>
void BubbleSort(T *sort, int size)
{
    for (int i = 0; i < size; ++i)
    {
        for (int j = 0; j < size - i - 1; ++j)
        {
            if (sort[j] > sort[j + 1])
            {
                Swap(sort[j], sort[j + 1]);
            }
        }
    }
}
/*改进版冒泡排序, 时间复杂度O(n*n)*/
template <class T>
void BubbleSort2(T *sort, int size)
{
    int end = size - 1;
    while (end > 0)
    {
        int i = 0;
        for (int j = 0; j < end; ++j)
        {
            if (sort[j] > sort[j + 1])
            {
                Swap(sort[j], sort[j + 1]);

                i = j;    //记录上一次排序排到了哪个位置
            }
        }
        end = i;
    }
}

/*双向冒泡排序(也就是鸡尾酒排序)*/
template <class T>
void ShakerSort(T *array, int size)
{
    int first = 0;
    int last = size - 1;
    int shift = 1;        /*从1开始可以保证数组访问不越界(元素未发生交换时shift的值就一直是初始值,此时有可能越界)*/
    while (first < last)
    {
        for (int i = first; i < last; i++)
        {
            if (array[i] > array[i + 1])
            {
                Swap(array[i], array[i + 1]);
                shift = i;
            }
        }
        last = shift;
        for (int i = last - 1; i >= first; i--)
        {
            if (array[i] > array[i + 1])
            {
                Swap(array[i], array[i + 1]);
                shift = i + 1;    /*注意这里为什么是i+1*/
            }
        }
        first = shift;
    }
}

/*选择排序*/
template <class T>
void SelectSort(T *array, int size)
{
    for (int i = 0; i < size; ++i)
    {
        for (int j = i + 1; j < size; ++j)
        {
            if (array[j] < array[i])
            {
                Swap(array[j], array[i]);
            }
        }
    }
}

/*插入排序*/
template <class T>
void InsertSort(T *array, int size)
{
    for (int i = 1; i < size; ++i)
    {
        T temp = array[i];
        int j  = i - 1;
        while (j >= 0 && array[j] > temp)    /*注意这里一定是temp 不能是array[i]*/
        {
            array[j + 1] = array[j];
            --j;
        }
        array[j + 1] = temp;
    }
}

/*计数排序(只考虑10000以内正整数)*/
template <class T>
void CountSort(T *array, int size)
{
    T sort[10000];
    T max = 0;
    for (size_t i = 0; i < size; i++)
    {
        sort[array[i]]++;
        if (max < array[i])
        {
            max = array[i];
        }
    }
    for (size_t i = 0, index = 0; i <= max; i++)
    {
        while (sort[i] > 0)
        {
            array[index++] = i;
            --sort[i];
        }
    }
}

/*基数排序*/

/*辅助函数,获取最大元素的位数*/

int maxbit(int *array, int size)
{
    int max = -1;
    for (size_t i = 0; i < size; i++)
    {
        if (max < array[i])
        {
            max = array[i];
        }
    }
    int digit = 0;
    while (max > 0)
    {
        ++digit;
        max /= 10;
    }
    return digit;
}

void put_in_bucket(int temp[][100], int number, int data)
{
    int j = 0;
    while (temp[number][j] != -1)
    {
        ++j;
    }
    temp[number][j] = data;
}

/*将数据copy回原来的数组中*/
void copy(int temp[][100], int *array)
{
    int index = 0;
    for (size_t i = 0; i < 10; i++)
    {
        int j = 0;
        while (temp[i][j] != -1)
        {
            array[index++] = temp[i][j];
            temp[i][j] = -1;
            ++j;
        }
    }
}

void radix_sort(int *array, int size)
{
    int temp[10][100];    /*临时数组,也就是桶*/
    memset(temp, -1, sizeof(temp));
    int radix = 1;        /*基数从个位开始*/
    int maxdigit = maxbit(array, size);
    int bit = 0;        /*记录当前已判断到哪一个分位*/
    while (bit < maxdigit)
    {
        
        for (size_t i = 0; i < size; i++)
        {
            int number = array[i];
            number = (number / radix) % 10;
            put_in_bucket(temp, number, array[i]);
        }
        copy(temp, array);
        radix *= 10;
        ++bit;
    }
}

/*希尔排序(改进版的插入排序)*/
template <class T>
void insert_sort(T* array, int size, int start, int increment)
{
    for (size_t i = start + increment; i < size; i += increment)
    {
        T temp = array[i];
        int j = i - increment;
        while (j >= start && array[j] > temp)    /*注意这里一定是temp 不能是array[i]*/
        {
            array[j + increment] = array[j];
            j -= increment;
        }
        array[j + increment] = temp;
    }
}
template <class T>
void ShellSort(T *array, int size)
{
    int increment = size;
    while (true)
    {
        increment = increment / size + 1;
        for (size_t i = 0; i < increment; i++)
        {
            insert_sort(array, size, i, increment);
        }
        if (increment <= 1)
        {
            break;
        }
    }
}

/*快速排序*/
template <class T>
int Partition(T *array, int first, int last)
{
    T temp = array[first];
    int i = first;
    int j = last;
    while (i < j)
    {
        while (i < j && array[j] >= temp)
        {
            --j;
        }
        array[i] = array[j];
        while (i < j && array[i] <= temp)
        {
            ++i;
        }
        array[j] = array[i];
    }
    array[i] = temp;
    return i;
}
template <class T>
void QuickSort(T *array, int first, int last)
{
    if (first < last)
    {
        int partition = Partition(array, first, last);
        QuickSort(array, first, partition - 1);
        QuickSort(array, partition + 1, last);
    }
}

/*非递归快排*/
template <class T>
void QuickSortByNonrecursive(T *array, int first, int last)
{
    stack<int> intStack;
    int middle;
    if (first < last)
    {
        intStack.push(first);
        intStack.push(last);

        while (!intStack.empty())
        {
            int j = intStack.top();
            intStack.pop();
            int i = intStack.top();
            intStack.pop();

            middle = Partition(array, i, j);
            if (i < middle - 1)
            {
                intStack.push(i);
                intStack.push(middle - 1);
            }
            if (j > middle + 1)
            {
                intStack.push(middle + 1);
                intStack.push(j);
            }
        }
        
    }
}

/*堆排序*/
template <class T>
void HeapShift(T *array, int size, int root)
{
    int lchild = root * 2;
    int rchild = root * 2 + 1;
    int max    = root;
    if (max <= size / 2)    //注意这里可以等于size
    {
        //lchild注意这里可以等于size
        if (lchild <= size && array[lchild - 1] > array[max - 1])
        {
            max = lchild;
        }
        if (rchild <= size && array[rchild - 1] > array[max - 1])
        {
            max = rchild;
        }
        if (max != root)
        {
            Swap(array[max - 1], array[root - 1]);
            HeapShift(array, size, max);
        }
    }
}
template <class T>
void HeapSort(T *array, int size)
{
    for (size_t i = size/2; i > 0; i--)
    {
        HeapShift(array, size, i);
    }
    for (size_t i = size; i > 0; i--)    //i从size开始
    {
        Swap(array[0], array[i - 1]);
        HeapShift(array, i - 1, 1);        //重新进行堆调整,注意这里的参数是 i-1, root一直是1,不是0
    }
}


/*归并排序(非递归)*/
template <class T>
void SingleMerge(T *array, int start, int middle, int end, T *container)
{
    int i = start;
    int j = middle + 1;
    int k = 0;
    while (i <= middle && j <= end)
    {
        if (array[i] <= array[j])
        {
            container[k++] = array[i++];
        }
        else
        {
            container[k++] = array[j++];
        }
    }
    while (i <= middle)
    {
        container[k++] = array[i++];
    }
    while (j <= end)
    {
        container[k++] = array[j++];
    }
}
template <class T>
void DoubleMerge(T *array, int size, int len, T *container)
{
    int start = 0;
    int end   = 0;
    int index = 0;
    while (start + len * 2 <= size)
    {
        end = start + len * 2 - 1;
        SingleMerge(array, start, start + len - 1, end, container + index);
        start = end + 1;
        index += len * 2;
    }
    if (start + len - 1 < size - 1)
    {
        SingleMerge(array, start, start + len - 1, size - 1, container + index);
    }
    else
    {
        for (size_t i = start; i < size; i++)
        {
            container[index++] = array[i];
        }
    }
}
template <class T>
void MergeSort(T *array, int size, T *container)
{
    int len = 1;
    while (len < size)
    {
        DoubleMerge(array, size, len, container);
        len *= 2;
        DoubleMerge(container, size, len, array);
    }
}

/*归并排序*/
template <class T>
void Merge(T *array, int start, int middle, int end, T *container)
{
    int i = start;
    int j = middle + 1;
    int k = start;        /*此函数与非递归的不同之处仅在这里*/
    while (i <= middle && j <= end)
    {
        if (array[i] <= array[j])
        {
            container[k++] = array[i++];
        }
        else
        {
            container[k++] = array[j++];
        }
    }
    while (i <= middle)
    {
        container[k++] = array[i++];
    }
    while (j <= end)
    {
        container[k++] = array[j++];
    }
}
template <class T>
void MergeSortByRecursive(T *array, int first, int last, T *container)
{
    if (first < last)
    {
        int mid = (first + last) / 2;
        MergeSortByRecursive(array, first, mid, container);
        MergeSortByRecursive(array, mid + 1, last, container);
        Merge(array, first, mid, last, container);        /*将排好序的两部分合并*/
        for (size_t i = first; i <= last; i++)            /*将数据复制回原数组array*/
        {
            array[i] = container[i];
        }
    }
}

/*链表的归并排序*/
template<class T>
struct ListNode {
    T elem;
    ListNode* next;
    ListNode() :next(NULL),elem(0){}
};

template<class T>
ListNode<T>* Merge(ListNode<T>*& _first, ListNode<T>*& _second)
{
    ListNode<T>* first = _first;
    ListNode<T>* second = _second;
    ListNode<T>* last;
    ListNode<T> combine;
    last = &combine;    /*这里用一个临时节点的好处是不用申请空间*/

    while (first != NULL && second != NULL)
    {
        if (first->elem <= second->elem)
        {
            last->next = first;
            last = first;     
            first = first->next;
        }
        else
        {
            last->next = second;
            last = second;
            second = second->next;
        }
    }
    if (first != NULL)
    {
        last->next = first;
    }
    else
    {
        last->next = second;
    }
    return combine.next;
}
template<class T>
ListNode<T>* DivideList(ListNode<T> *&sublist)
{
    ListNode<T> *slow = sublist;
    ListNode<T> *fast = sublist->next;

    while (fast != NULL)
    {
        fast = fast->next;
        if (fast != NULL)
        {
            fast = fast->next;
            slow = slow->next;
        }
        else
        {
            continue;
        }
    }
    ListNode<T> *middle = slow->next;    /*返回后半部分的第一个节点*/
    slow->next = NULL;
    return middle;
}
template<class T>
void recursive_merge_sort(ListNode<T> *&listhead)
{
    /*仅当链表节点数多于一个时才归并*/
    if (listhead != NULL && listhead->next != NULL)
    {
        ListNode<T> *sublist = DivideList(listhead);    /*将链表截成两部分*/
        recursive_merge_sort(listhead);
        recursive_merge_sort(sublist);
        listhead = Merge(listhead, sublist);        /*记得把归并后的子链表头结点赋给listhead*/
    }
    else
    {
        return;
    }
}

/*奇偶排序算法*/
template<class T>
void odd_even_sort(T *array, int size)
{
    bool flag = true;
    while (flag)
    {
        flag = false;
        for (size_t i = 0; i < size - 1; i += 2)
        {
            if (array[i] > array[i + 1])
            {
                Swap(array[i], array[i + 1]);
                flag = true;
            }
        }
        for (size_t i = 1; i < size - 1; i += 2)
        {
            if (array[i] > array[i + 1])
            {
                Swap(array[i], array[i + 1]);
                flag = true;
            }
        }
    }
}

int main()
{
    int array[100], t[100];
    int length = 20;
    srand(time(NULL));
    ListNode<int> *node = new ListNode<int>;
    ListNode<int> *head = node;
    cout << "原数组元素:\n";
    for (size_t i = 0; i < length; i++)
    {
        array[i] = rand() % 1000;
        node->elem = array[i];
        node->next = new ListNode<int>;
        node = node->next;
        cout << array[i] << " ";
    }
    cout << "\n排序后:\n";
    //BubbleSort(array, length);
    //BubbleSort2(array, length);
    //ShakerSort(array, length);
    //SelectSort(array, length);
    //QuickSort(array, 0, length - 1);
    //QuickSortByNonrecursive(array, 0, length-1);
    //HeapSort(array, length);
    //MergeSort(array, length, t);
    //MergeSortByRecursive(array, 0, length - 1, t);
    //ShellSort(array, length);
    //radix_sort(array, length);
    //odd_even_sort(array, length);
    for (size_t i = 0; i < length; i++)
    {
        cout << array[i] << " ";
    }
    cout << endl;

    recursive_merge_sort(head);
    head = head->next;
    while (head != NULL)
    {
        cout << head->elem << " ";
        head = head->next;
    }
    
    cout << endl;
    /*/
    bool flag = true;
    for (size_t i = 1; i < length; i++)
    {
        if (array[i] < array[i - 1])
        {
            flag = false;
        }
    }
    cout << "\n排序是否正确:" << flag << endl;
    */
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值