排序算法学习记录

排序算法学习记录

排序在很多场合中都经常用到,排序算法属于很常用的算法之一,在此对几种经典的排序算法进行简单的讲解,主要包括简单排序中的选择排序,冒泡排序,插入排序,以及快排,归并排序,希尔排序等。

1.选择排序

选择排序的主要思想是先从所有的元素中选取一个最小的元素,与最左边的数进行位置交换,然后从第二个元素到最后一个元素中再取一个最小的元素,与左边第二个数进行交换,依次循环下去。

vector<int> Select_Sort(vector<int>nums) {
    int min_value = INT_MAX, min_index = 0;
    int len = nums.size();
    for (int i = 0; i < len; i++) {
        min_value = INT_MAX;
        for (int j = i; j < len; j++) {
            if (nums[j] < min_value) {
                min_value = nums[j];//记录最小值
                min_index = j;//记录最小值的位置
            }
        }
        swap(nums[i], nums[min_index]);//将最小值移至左边
    }
    return nums;
}

时间复杂度:O(n^2),空间复杂度:O(1)

2. 冒泡排序

类似于冒泡的原理,将一个元素与后续元素依次作比较,若满足条件则进行位置交换,使得该元素逐渐向后移。

vector<int>Bubble_Sort(vector<int>nums) {
    int len = nums.size();
    for (int i = nums.size()-1; i>0; i--) {
        for (int j = 0; j <i; j++) {
            if (nums[j] > nums[j+1])swap(nums[j], nums[j+1]);
        }
    }
    return nums;
}

时间复杂度:O(n^2),空间复杂度:O(1)

3.插入排序

插入排序的思想是不断使前面一部分元素保持有序状态。假定前a个元素为有序状态,需要插入第a+1个元素,将第a+1个元素依次与前a个元素进行比较,并在合适的位置的进行插入,使a+1个元素保持有序。

vector<int>Insert_Sort(vector<int>nums) {
    int len = nums.size();
    for (int i =1; i< nums.size() ; i++) {
        for (int j = i; j>0; j--) {
            if (nums[j] < nums[j - 1])swap(nums[j], nums[j - 1]);
        }
    }
    return nums;
}

时间复杂度:O(n^2),空间复杂度:O(1)

4. 归并排序

归并排序用到了递归及合并两个操作,合并操作主要是将左右两边均有序的数组变成一个有序的数组,而递归操作是不断重复上述过程,不断合并数组,最终使所有元素变成有序。

void Merge(vector<int>&nums, int leftptr, int rightptr, int rightbound) {
    vector<int>temp(rightbound - leftptr + 1, 0);
    int i = leftptr, j = rightptr, k = 0;
    int mid = rightptr - 1;
    while (i <= mid && j <= rightbound) {
        temp[k++] = nums[i] < nums[j] ? nums[i++]:nums[j++];
    }
    while (i <= mid)temp[k++] = nums[i++];
    while (j <= rightbound)temp[k++] = nums[j++];
    //将排好序的元素放入nums中
    for (int m = 0; m < temp.size(); m++) {
        nums[m + leftptr] = temp[m];
    }
}
void TS(vector<int>&nums, int left, int right) {
    //递归终止条件
    if (left == right)return;
    //对序列进行切分
    int mid = left + (right - left) / 2;
    //对左边进行排序
    TS(nums,left, mid);
    //对右边进行排序
    TS(nums, mid + 1, right);
    //对排好序的左右两边进行合并
    Merge(nums,left,mid+1,right);
}
vector<int>MergetSort(vector<int>&nums) {
    TS(nums, 0, nums.size()-1);
    return nums;
}

时间复杂度:O(n*log(n)) 空间复杂度:O(n)

5.希尔排序

是优化的选择排序,每取一个间隔gap的所有元素进行排序

vector<int>Shell_Sort(vector<int>nums) {
    //选择最优gap长度
    int h = 1;
    while (h <= nums.size() / 3) {
        h = h * 3 + 1;
    }
    for (int gap = h; gap > 0; gap =(gap-1)/3) {
        for (int i = gap; i < nums.size(); i++) {
            for (int j = i; j > gap-1; j -= gap) {
                if (nums[j] < nums[j - gap])swap(nums[j], nums[j - gap]);
            }
        }
    }
    return nums;
}

时间复杂度:O(n^1.3) 空间复杂度:O(1)

6. 单轴快排

int get_pivot(vector<int>& nums, int left,int right) {
    int pivot = right;
    int i = left, j = right - 1;
    while (i <= j) {
        while (i <= j && nums[i] <= nums[pivot])i++;
        while (i <= j && nums[j] > nums[pivot])j--;
        if (i <= j)swap(nums[i++], nums[j--]);
    }
    swap(nums[i], nums[pivot]);
    return i;
}

void Sort(vector<int>& nums,int left,int right) {
    if (left >= right)return;
    int rand_position = left + rand() % (right - left);
    swap(nums[rand_position], nums[right]);
    int pivot = get_pivot(nums, left, right);
    Sort(nums, left, pivot - 1);
    Sort(nums, pivot + 1, right);
}
vector<int>QuickSort(vector<int>&nums) {
    Sort(nums,0, nums.size() - 1);
    return nums;
}

时间复杂度:O(n*log(n)) 空间复杂度:O(log(n))

7.使用对数器进行算法验证

#include <iostream>
#include <vector>//要使用vector必须包含vector头文件
#include<stdlib.h>//产生随机数的rand包含在此头文件中
#include<algorithm>
using namespace std;

//data_cheker对数器
vector<int>Generation() {
    int len = 1000;
    vector<int>nums;
    for (int i = 0; i < len; i++) {
        nums.push_back(rand());
    }
    return nums;
}

int main()
{
    int times = 1000;
    bool result = true;
    while (times > 0) {
        vector<int>nums1 = Generation();
        vector<int>nums2 = nums1;
        sort(nums1.begin(), nums1.end());
        nums2 = QuickSort(nums2);//修改相应的排序算法名称即可
        for (int i = 0; i < nums2.size(); i++) {
            if (nums1[i] != nums2[i]) {
                result = false;
                break;
            }
        }
        if (result == false)break;
        times--;
    }
    if (result == false)cout << "算法不正确" << endl;
    else cout << "测试案例全部通过。" << endl;
    return 0;
}
  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值