十大排序算法 c++

十大排序算法

力扣题目链接:912. 排序数组 - 力扣(LeetCode)

原理:1.0 十大经典排序算法 | 菜鸟教程 (runoob.com)

代码

class Solution {
public:
    //冒泡排序,时间O(n^2), 空间O(1)
    void bubbleSort(vector<int>& nums) {
        for (int i = 0; i < nums.size() - 1; ++i) {
            for (int j = 0; j < nums.size() - i - 1; ++j) {
                if (nums[j] > nums[j + 1]) {
                    int tem = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = tem;
                }
            }
        }
    }

    //选择排序,时间O(n^2), 空间O(1)
    void selectSort(vector<int>& nums) {
        for (int i = 0; i < nums.size() - 1; ++i) {
            int ind = i;
            for (int j = i + 1; j < nums.size(); j++) {
                if (nums[j] < nums[ind]) {
                    ind = j;
                }
            }
            if (ind != i) {
                std::swap(nums[i], nums[ind]);
            }
        }
    }

    //插入排序,时间O(n^2), 空间O(1)
    void insertSort(vector<int>& nums) {
        for (int i = 1; i < nums.size(); ++i) {
            if (nums[i] >= nums[i -1]) continue;
            int tem = nums[i];
            int j = i - 1;
            while (j >= 0 && nums[j] > tem) {
                nums[j + 1] = nums[j];
                j--;
            }
            nums[j + 1] = tem;
        }
    }

    //希尔排序,时间O(nlog(n)), 空间O(1)
    void shellSort(vector<int>& nums) {
        int gap = nums.size();
        while (gap > 1) {
            gap = gap / 3 + 1;
            for (int i = gap; i < nums.size(); i++) {
                if (nums[i] >= nums[i - gap]) continue;
                int tem = nums[i];
                int j = i - gap;
                while (j >= 0 && nums[j] > tem) {
                    nums[j + gap] = nums[j];
                    j -= gap;
                }
                nums[j + gap] = tem;
            }
        }
    }

    void merge(vector<int>& nums, int ibegin, int mid, int iend) {
        vector<int> leftNums(nums.begin() + ibegin, nums.begin() + mid + 1);
        vector<int> rightNums(nums.begin() + mid + 1, nums.begin() + iend + 1);
        int idxLeft = 0, idxRight = 0;
        // leftNums[leftNums.size() - 1] = INT_MAX;
        // rightNums[rightNums.size() - 1] = INT_MAX;
        leftNums.insert(leftNums.end(), INT_MAX);
        rightNums.insert(rightNums.end(), INT_MAX);
        for (int i = ibegin; i <= iend; ++i) {
            if (leftNums[idxLeft] < rightNums[idxRight]) {
                nums[i] = leftNums[idxLeft];
                idxLeft++;
            }
            else {
                nums[i] = rightNums[idxRight];
                idxRight++;
            }
        }
    }
    //归并排序,时间O(nlog(n)), 空间O(n)
    void merge_sort(vector<int>& nums, int ibegin, int iend) {
        if (ibegin < iend) {
            int mid = (ibegin + iend) / 2;
            merge_sort(nums, ibegin, mid);
            merge_sort(nums, mid + 1, iend);
            merge(nums, ibegin, mid, iend);
        }

    }

    // 随机快排,双指针,时间O(nlog(n)),空间O(log(n))
    void quick_sort(vector<int>& nums, int ibegin, int iend) {
        if (ibegin >= iend) {
            return;
        }
        int index = rand() % (iend - ibegin + 1) + ibegin;
        swap(nums[iend], nums[index]);
        int tem = nums[iend];
        int left = ibegin;
        int right = iend - 1;
        while (left <= right) {
            while (left <= right && nums[left] < tem) {
                left++;
            }
            while (left <= right && nums[right] > tem) {
                right--;
            }
            if (left <= right) swap(nums[left++], nums[right--]);
        }
        // nums[iend] = nums[left];
        // nums[left] = tem;
        swap(nums[iend], nums[left]);
        quick_sort(nums, ibegin, left - 1);
        quick_sort(nums, left + 1, iend);
    }

    int partition(vector<int>& nums, int l, int r) {
        int pivot = nums[r];
        int i = l - 1;
        for (int j = l; j <= r - 1; ++j) {
            if (nums[j] <= pivot) {
                i = i + 1;
                swap(nums[i], nums[j]);
            }
        }
        swap(nums[i + 1], nums[r]);
        return i + 1;
    }
    int randomized_partition(vector<int>& nums, int l, int r) {
        int i = rand() % (r - l + 1) + l; // 随机选一个作为我们的主元
        swap(nums[r], nums[i]);
        return partition(nums, l, r);
    }
    // 官方随机快排
    void randomized_quicksort(vector<int>& nums, int l, int r) {
        if (l < r) {
            int pos = randomized_partition(nums, l, r);
            randomized_quicksort(nums, l, pos - 1);
            randomized_quicksort(nums, pos + 1, r);
        }
    }

    void maxHeapify(vector<int>& nums, int i, int len) {
        while ((i << 1) + 1 <= len) {
            int lson = (i << 1) + 1;
            int rson = (i << 1) + 2;
            int large = i;
            if (lson <= len && nums[lson] > nums[i]) large = lson;
            if (rson <= len && nums[rson] > nums[large]) large = rson;
            if (large != i) {
                swap(nums[i], nums[large]);
                i = large;
            } else {
                break;
            }
        }
    }

    void buildMaxHeap(vector<int>& nums, int len) {
        for (int i = (len - 1) / 2; i >= 0; --i) {
            maxHeapify(nums, i, len);
        }
    }

    // 堆排序,时间O(nlog(n)),空间O(1)
    void heap_sort(vector<int>& nums) {
        int len = nums.size() - 1;
        buildMaxHeap(nums, len);
        for(int i = len; i > 0; --i) {
            swap(nums[0], nums[i]);
            --len;
            maxHeapify(nums, 0, len);
        }
    }

    // 计数排序,时间O(n+k),空间O(n+k)
    vector<int> count_sort(vector<int>& nums) {
        int len = nums.size();
        vector<int> newNums(len);
        int min = INT_MAX, max = INT_MIN;
        for (auto n : nums) {
            if (n < min) min = n;
            if (n > max) max = n;
        }
        int k = max - min + 1;
        vector<int> countNums(k);
        for (auto n : nums) {
            countNums[n - min]++;
        }
        for (int i = 1; i < countNums.size(); ++i) {
            countNums[i] += countNums[i - 1];
        }
        for (int i = 0; i < nums.size(); ++i) {
            newNums[--countNums[nums[i] - min]] = nums[i];
        }
        return newNums;
    }

    // 桶排序,时间O(n+k),空间O(n+k)
    void bucket_sort(vector<int>& nums) {
        int len = nums.size();
        int bucketNum = sqrt(len);
        // int bucketNum = len / 2 + 1;
        vector<vector<int>> bucket(bucketNum);
        int min = INT_MAX, max = INT_MIN;
        for (auto n : nums) {
            if (n < min) min = n;
            if (n > max) max = n;
        }
        int cu = ceil(float(max - min + 1) / bucketNum);
        for (auto n : nums) {
            bucket[(n - min) / cu].push_back(n);
        }
        for (int i = 0; i < bucketNum; ++i) {
            quick_sort(bucket[i], 0, bucket[i].size() - 1);
        }
        int ind = 0;
        for (int i = 0; i < bucketNum; ++i) {
            for (int j = 0; j < bucket[i].size(); ++j) {
                nums[ind++] = bucket[i][j];
            }
        }
    }

    // 基数排序,时间O(n*k),空间O(n+k)
    void radix_sort(vector<int>& nums) {
        int maxNum = INT_MIN;
        int minNum = INT_MAX;
        for (auto n : nums) {
            if (n < minNum) minNum = n;
            if (n > maxNum) maxNum = n;
        }
        if (minNum < 0) {
            for (auto& n : nums) {
                n -= minNum;
            }
            maxNum -= minNum;
        }
        int nbit = 0;
        while (maxNum > 0) {
            maxNum /= 10;
            nbit++;
        }
        vector<int> countNums(10); // 计数排序
        vector<int> tem(nums.size());
        int radix = 1;
        // cout << nbit;
        for (int i = 0; i < nbit; ++i) {
            for (int j = 0; j < 10; ++j) {
                countNums[j] = 0;
            }
            for (auto n : nums) {
                int ind = (n / radix) % 10;
                countNums[ind]++;
            }
            for (int j = 1; j < 10; ++j) {
                countNums[j] += countNums[j - 1];
            }
            for (int j = nums.size() - 1; j >= 0; --j) {
                tem[--countNums[(nums[j] / radix) % 10]] = nums[j];
            }
            for (int j = 0; j < nums.size(); ++j) {
                nums[j] = tem[j];
            }
            radix *= 10;
        }
        if (minNum < 0) {
            for (auto& n : nums) {
                n += minNum;
            }
        }
    }

    vector<int> sortArray(vector<int>& nums) {
        radix_sort(nums);
        return nums;
        // return count_sort(nums);
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值