常用排序算法总结

// 11类常用算法代码实现
//

#include <iostream>
#include<vector>
using namespace std;


//1.直接插入排序 O(n^2)
template<class T>
void Insert(vector<T>* a)
{
    size_t N = (*a).size();
    for (int i = 1; i < N; i++)
    {
        if ((*a)[i] < (*a)[i - 1])
        {
            int j = i - 1;
            T tmp = (*a)[i];
            while (j >= 0 && tmp < (*a)[j])
            {
                (*a)[j + 1] = (*a)[j];
                j--;
            }
            (*a)[j + 1] = tmp;
        }
    }
}


//2.折半插入排序
template<class T>
void BInsert(vector<T>* a)
{
    size_t N = (*a).size();
    for (int i = 1; i < N; i++)
    {
        if ((*a)[i] < (*a)[i - 1])
        {
            int low = 0, high = i - 1,mid;
            T tmp = (*a)[i];
            while (low <= high)
            {
                mid = (low + high) / 2;
                if ((*a)[mid] > tmp) high = mid - 1;
                else low = mid + 1;
            }
            // 有序表中插入位置后的元素都后移一步
            for (int j = i; j > low; j--) (*a)[j] = (*a)[j - 1];
            (*a)[low] = tmp;
        }
    }
}

//3. 2路插入排序
template<class T>
void Insert2(vector<T>* a)
{
    size_t N = (*a).size();
    vector<T> d(N);
    int start, end;
    start = end = 0;
    d[0] = (*a)[0];

    for (int i = 1; i < N; i++)
    {
        if ((*a)[i] < d[start])
        {
            start = (start - 1 + N) % N;
            d[start] = (*a)[i];

        }
        else if ((*a)[i] > d[end])
        {
            end = (end + 1 + N) % N;
            d[end] = (*a)[i];
        }
        else
        {
            int k= (end + 1 + N) % N;
            while (d[(k - 1 + N) % N] > (*a)[i])
            {
                d[(k + N) % N] = d[(k - 1 + N) % N];
                k = (k - 1 + N) % N;
            }
            d[(k + N) % N] = (*a)[i];
            end = (end + 1 + N) % N;
        }
    }
    for (int i = 0; i < N; i++)
    {
        (*a)[i] = d[(start + i) % N];
    }
}

template<class T>
void printAns(vector<T> a)
{
    for (auto elem : a) cout << elem << " ";
    cout << endl;
}


template<class T>
void swap(T* a, T* b)
{
    int tmp;
    tmp = *a;
    *a = *b;
    *b = tmp;
}

//4.冒泡排序
template<class T>
void bubble(vector<T>* a)
{
    int N = (*a).size();
    
    for (int i = 0; i < N; i++)
    {
        bool flag = true;
        for (int j = 0; j < N - i - 1; j++) 
        {
            if ((*a)[j] > (*a)[j + 1])
            {
                flag = false;
                swap(&(*a)[j], &(*a)[j + 1]);
            }
        }
        if (flag) break;
    }
}


// 分割操作
template<class T>
int partition(vector<T>* a,int low,int high)
{
    int pivot = (*a)[low];//支点
    while (low < high)
    {
        while (low < high && (*a)[high] >= pivot)
        {
            high--;
        }
        swap(&(*a)[low], &(*a)[high]);
        while (low < high && (*a)[low] <= pivot)
        {
            low++;
        }
        swap(&(*a)[low], &(*a)[high]);
    }
    return low;
}

template<class T>
void qSort(vector<T>* a,int low,int high)
{
    if (low < high)
    {
        int pivot = partition(a, low, high);
        qSort(a, low, pivot - 1);
        qSort(a, pivot + 1, high);
    }
}

//6.快排
template<class T>
void qSort(vector<T>* a)
{
    qSort(a, 0, (*a).size() - 1);
}

//找最小值所在下标
template<class T>
int minIdx(vector<T>* a, int idx)
{
    int min = idx;
    int N = (*a).size();
    for (int i = idx + 1; i < N; i++)
    {
        if ((*a)[min] > (*a)[i]) min = i;
    }
    return min;
}

//7.选择排序
template<class T>
void selectSort(vector<T>* a)
{
    int N = (*a).size();
    for (int i = 0; i < N; i++)
    {
        int idx = minIdx(a, i);
        if (i != idx) swap((*a)[i], (*a)[idx]);
    }
}


template<class T>
int selectMin(vector<T> *a, vector<int> record)
{
    if (record.size() == 1)
    {
        return record.back();
    }
    int N = record.size();
    vector<int> halfRecord;
    
    N = N / 2;
    int tmp;
    for (int i = 0; i < N; i++)
    {
        tmp = record[2 * i];
        if ((*a)[record[2 * i]] > (*a)[record[2 * i + 1]])
        {
            tmp = record[2 * i + 1];
        }
        halfRecord.push_back(tmp);
    }
    if (record.size() % 2 == 1)
    {
        halfRecord.push_back(record.back());
    }
    return selectMin(a, halfRecord);
   
}

// 8.树型选择排序
template<class T>
void treeSort(vector<T>* a)
{
    vector<int> record;
    vector<T> tmp(*a);
    for (int i = 0; i < (*a).size(); i++)
    {
        record.push_back(i);
    }
    for (int i = 0; i < (*a).size(); i++)
    {
        int idx= selectMin(&tmp, record);
        (*a)[i] = tmp[idx];
        tmp[idx] = INT_MAX;
    }
}



template<class T>
void adjust(vector<T>* a, int s,int N)
{
    T rc = (*a)[s];
    for (int i = 2 * s + 1; i < N; i = i * 2 + 1)
    {
        if (i + 1 < N && (*a)[i] < (*a)[i + 1]) i++;
        if (rc >=(*a)[i]) break; // 无需调整
        (*a)[s] = (*a)[i]; 
        s = i;
    }
    (*a)[s] = rc;
}

//9.堆排序
template<class T>
void heapSort(vector<T>* a)
{
    int N = (*a).size();
    //构建堆
    for (int i = (*a).size() / 2; i >= 0; i--)
    {
        adjust(a, i,N);
    }
    //调整剩余元素构建一个新堆
    for (int i = (*a).size()-1; i >=0; i--) 
    {
        swap(&(*a)[0], &(*a)[i]);
        adjust(a, 0,i-1);
    }
}


//10.归并排序
template<class T>
void mergeSort(vector<T>* a, int lo, int hi,int mid)
{
    vector<T> tmp(hi - lo + 1); // 存放需要归并排序的数组
    int i, j, k;
    
    for (k = lo; k <= hi; k++)
    {
        tmp[k - lo] = (*a)[k];
    }
    i = lo;  // 左半边
    j = mid + 1; // 右半边
    for (k = lo; k <= hi; k++)
    {
        if (i > mid)  // 只有右半边有用
        {
            (*a)[k] = tmp[j - lo];
            j++;
        }
        else if (j > hi) // 只有左半边有用
        {
            (*a)[k] = tmp[i - lo];
            i++;
        }
        else if (tmp[i - lo] > tmp[j - lo]) // 右边更小
        {
            (*a)[k] = tmp[j - lo];
            j++;
        }
        else // 左边更小
        {
            (*a)[k] = tmp[i - lo];
            i++;
        }
    }

}
template<class T>
void mergeSort(vector<T>* a,int lo,int hi)
{
    if (lo >= hi) return;
    int mid = (lo + hi) / 2;
    mergeSort(a, lo, mid);
    mergeSort(a, mid + 1, hi); // 相当于是后续遍历,从左右到根
    mergeSort(a, lo, hi, mid);
}
template<class T>
void mergeSort(vector<T>* a)
{
    mergeSort(a, 0, (*a).size()-1);
}

//11.基数排序
template<class T>
void distruib(vector<T>* a,int digit)// 分配和收集算法
{
    vector<vector<T>> tmp(10);
    int s = pow(10, digit-1);
    int elem;
    for(int i=0;i<(*a).size();i++)
    {
        elem = (*a)[i] / s;
        elem = elem % 10;
        tmp[elem].push_back((*a)[i]);
    }
    int idx = 0;
    for (auto vec : tmp)
    {
        for (int i = 0; i < vec.size(); i++)
        {
            (*a)[idx++] = vec[i];
        }
    }
}
template<class T>
int maxDigit(vector<T>* a) // 最大位数
{
    int maxElem = (*a).front();
    for(int i=1;i<(*a).size();i++)
    {
        if ((*a)[i] > maxElem) maxElem = (*a)[i];
    }
    int ret = 0;
    while (maxElem > 0)
    {
        maxElem = maxElem / 10;
        ret++;
    }
    return ret;
}
template<class T>
void radixSort(vector<T>* a)
{
    int num=maxDigit(a);//循环次数
    for (int i = 1; i <= num; i++)
    {
        distruib(a, i);
    }
    return;
}

int main()
{
    //vector<int> ArrDirInser{ 3,1,7,5,2,4,9,6 };
    vector<int> ArrDirInser{50,123,543,187,49,30,0,2,11,100};
    //1.
    //Insert(&ArrDirInser);
    //BInsert(&ArrDirInser);
    //Insert2(&ArrDirInser);
    //bubble(&ArrDirInser);

    //qSort(&ArrDirInser);
    //selectSort(&ArrDirInser);
    //treeSort(&ArrDirInser);
    //heapSort(&ArrDirInser);
    //mergeSort(&ArrDirInser);
    radixSort(&ArrDirInser);

    printAns(ArrDirInser);


    std::cout << "Hello World!\n";
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值