有关排序

冒泡排序

void bubbleSort(vector<int>& vec)
{
    if (vec.size() == 0)
        return;
    for (int i = 0; i < vec.size(); i++) {
        bool flag = false;
        for (int j = vec.size()-1; j > i; j--) {
            if (vec[j] < vec[j - 1]) {
                swap(vec[j], vec[j - 1]);
                flag = true;
            }
        }
        if (!flag)
            return;
    }

}

冒泡排序算法性能分析如下:
空间复杂度O(1),最坏的情况下时间复杂度为O(n2),最坏情况下(表中元素基本有序)时间复杂度为O(n),其平均时间复杂度为O(n2)
稳定性:冒泡排序是稳定的排序方法

快速排序

int partion(vector<int>& vec, int left, int right)
{
    swap(vec[left], vec[right]);
    int pivot = left - 1;
    int index = left;
    while (index < right) {
        if (vec[index] < vec[right])
            swap(vec[++pivot], vec[index++]);
        else
            ++index;
    }
    swap(vec[++pivot], vec[right]);
    return pivot;
}

void quickSortCore(vector<int>& vec, int left, int right)
{
    if (left > right)
        return;
    int index = partion(vec, left, right);
    quickSortCore(vec, left, index - 1);
    quickSortCore(vec, index + 1, right);
}


void quickSort(vector<int>& vec)
{
    quickSortCore(vec, 0, vec.size()-1);
}

注意:这里partion函数有两种划分方法

int partion2(vector<int>&vec, int left, int right)
{
    int pivot = vec[left];
    while (left < right) {
        while (left < right && vec[right] >= pivot) --right;
        vec[left] = vec[right];
        while (left < right && vec[left] <= pivot) ++left;
        vec[right] = vec[left];
    }
    vec[left] = pivot;
    return left;
}

第一种有一个特点,即一次划分后,枢纽左边的元素相对顺序不变
空间效率:
由于快速排序是递归的,需要借助一个递归工作栈来保存每一层递归调用的必要信息,其容量应与递归调用的最大深度一致。最好情况下为(log2(n+1));最坏的情况下因为要进行n-1次递归调用,所以栈的深度为O(n);平均情况下,栈的深度为O(log2n)
时间效率:
快速排序的最坏情况发生在两个区域分别包含n-1个元素和0个元素时, 而后者又与具体使用的划分算法有关。这种最大程度的不对称性发生在每一层递归上,即对应于初始排序表基本有序或基本逆序时,就得到最坏下的时间复杂度(O(n2)),平均时间复杂度为(nlog2n)
快速排序是所有内部排序算法中平均性能最优的排序算法。
稳定性:
在划分算法中,若右端区间存在量个关键字相同,且均小于基准值的记录,则在交换到左端区间后,它们的相对位置会发生变化,快速排序是一个不稳定的排序算法。

选择排序

void chooseSort(vector<int>& vec)
{
    for (int i = 0; i < vec.size(); i++) {
        int min = i;
        for (int j = i; j < vec.size(); j++) {
            if (vec[j] < vec[min])
                min = j;
        }

        swap(vec[i], vec[min]);
    }
}

性能分析:
空间复杂度O(1)
时间复杂度:元素间的比较次数与序列的初始状态无关,始终是n(n-1)/2次,时间复杂度始终为O(n2)

堆排序

int inline leftChild(int num)
{
    return 2 * num + 1;
}

void CreateHeap(vector<int>& vec, int index, int n)
{
    int child;
    int tmp = vec[index];
    for (; leftChild(index) < n; index = child) {
        child = leftChild(index);
        if (child + 1 < n &&  vec[child] < vec[child + 1])
            child++;
        if (vec[child] > vec[index])
            swap(vec[index] , vec[child]);
        else
            break;
    }
    vec[index] = tmp;

}

void heapSort(vector<int>& vec)
{
    for (int i = vec.size() / 2 - 1; i >= 0; i--) {
        CreateHeap(vec, i, vec.size());
    }
    for (int j = vec.size() - 1; j >= 0; j--) {
        swap(vec[0], vec[j]);
        CreateHeap(vec, 0, j);
    }
}

堆排序的性能分析:
空间效率:仅使用了常数个辅助单元,所以空间复杂度O(1)
时间效率:在最好、最坏和平均情况下,堆排序的时间复杂度为O(nlog2n)
稳定性:不稳定

归并排序

void merge(vector<int>&vec, int left, int mid, int right)
{
    int low = left;
    int high = mid + 1;
    vector<int> tmpArray(right - left + 1);
    int index = 0;
    while (low <= mid && high <= right) {
        if (vec[low] < vec[high])
            tmpArray[index++] = vec[low++];
        else
            tmpArray[index++] = vec[high++];
    }
    while (low <= mid)
        tmpArray[index++] = vec[low++];
    while (high <= right)
        tmpArray[index++] = vec[high++];

    index = 0;
    for (int i = left; i <= right; i++) {
        vec[i] = tmpArray[index++];
    }
}

void mergeSortCore(vector<int>&vec, int left, int right)
{
    if (left >= right)
        return;
    int mid = (left + right) / 2;
    mergeSortCore(vec, left, mid);
    mergeSortCore(vec, mid + 1, right);

    merge(vec, left, mid, right);

}

void mergeSort(vector<int>& vec)
{
    mergeSortCore(vec, 0, vec.size()-1);
}

归并排序的性能分析
空间效率:辅助空间刚好占用n个单元,空间复杂度为O(n)
时间效率:每一趟归并的时间复杂度O(n),共需进行(log2n)趟归并,所以算法时间复杂度为O(nlog2n).
稳定性:由于Merge()操作不会改变相同关键字记录的相对次序,所以二路归并排序算法是一个稳定的而排序方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值