C++ 选择排序、冒泡排序、插入排序

选择排序:是一种简单直观的排序算法,每次均是选择最小(大)的元素进行排序。

选择排序算法思想:1 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置

2 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾

重复第2步,直到排序完成、时间复杂度为 n^2 空间复杂度为 1

这种算法的优点是时间复杂度高,并且会改变相同元素的相对位置,因此这个是一种不稳定的排序算法

代码练习1,对应力扣 颜色分类,代码见下

cpp 复制代码
class Solution {
public:
    void selectionSort(vector<int>& a){
        int n = a.size();
        for(int i = 0; i<n; ++i){
            int min = i;
            for(int j = i+1; j<n; ++j){
                if(a[min] > a[j]){
                   min = j; 
                }
            }
            int tmp = a[min];
            a[min] = a[i];
            a[i] = tmp;
        }
    } 
    void sortColors(vector<int>& nums) {
        selectionSort(nums);
    }
};

冒泡排序:是一种简单的排序算法,通过多次比较和交换相邻的元素,将数组中的元素按升序或降序排列

冒泡排序的算法思想:

1 遍历数组的第一个元素到最后一个元素

2 对每一个元素,与后一个元素进行比较

3 如果顺序错误,就将他们交换

重复上述步骤,直至数组中的所有元素至少被遍历过一次

冒泡排序的时间复杂度为0(n^2),空间复杂度为0(1)

冒泡排序的算法优点:是一种稳定的算法,不会改变相同元素的相对位置,缺点便是效率低下,时间复杂度较高

代码一,对应力扣,合并两个有序数组,代码见下

cpp 复制代码
class Solution {
    void bubbleSort(vector<int>& a){
        int n = a.size();
        for(int i = n-1; i>=0; --i){
            for(int j=0; j<i; ++j){
                if(a[j] > a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                }
            }
        }

    }
public:
    void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
        for(int i=0; i<nums2.size(); ++i){
            nums1[m+i] = nums2[i];

        }
        bubbleSort(nums1);
    }
};

代码2 对应力扣,最后一块石头的重量,代码见下:

cpp 复制代码
class Solution {
    void bubbleSort(vector<int>& a){
        int n = a.size();
        for(int i=n-1; i>=0; --i){
            for(int j=0; j<i; ++j){
                if(a[j] > a[j+1]){
                    int tmp = a[j];
                    a[j] = a[j+1];
                    a[j+1] = tmp;
                }
            }
        }

    }
public:
    int lastStoneWeight(vector<int>& stones) {
        while(stones.size() > 1){
            bubbleSort(stones);
            int n = stones.size();
            int v = stones[n-1] - stones[n-2];
            stones.pop_back();
            stones.pop_back();
            if(v || stones.size() == 0){
                stones.push_back(v);
            }
        }
        return stones[0];
    }
};

插入排序:工作原理是通过构建有序序列,对于未排序序列,在已排序序列中从后往前扫描,找到对应位置插入,从而使得有序。

算法步骤:1 从第一个元素开始,将它视为已排序部分

2 取出下一个元素,与已排序的元素进行比较

3 如果该元素小于已排序部分的最后一个部分,则将其插入到已排序部分的适当位置,重复 2和3直到完成排序

插入排序的时间复杂度为O(n^2),空间复杂度为O(1)

代码练习 1,对应力扣,去掉最低工资和最高工资后的工资平均值,代码见下

cpp 复制代码
class Solution {
    void insertSection(vector<int>& a){
        for(int i=1; i<a.size(); ++i){
            int x = a[i];
            int j;
            for( j=i-1; j>=0; --j){
                if(x < a[j]){
                    a[j+1] = a[j];
                }else{
                    break;
                }
            }
            a[j+1] = x;
        }
    }
public:
    double average(vector<int>& salary) {
        insertSection(salary);
        int n = salary.size();
        double sum = 0;
        for(int i=1; i<n-1; ++i){
            sum += salary[i];
        }
        return sum / (n-2);
    }
};

代码 2,对应力扣删除某些元素后的数组均值,代码见下

cpp 复制代码
class Solution {
    void insertionSort(vector<int>& a){
        for(int i=1; i<a.size(); ++i){
            int x = a[i];
            int j;
            for(j=i-1; j>=0; --j){
                if(x < a[j]){
                    a[j+1] = a[j];
                }else{
                    break;
                }
            }
            a[j+1] = x;
        }
    }
public:
    double trimMean(vector<int>& arr) {
        insertionSort(arr);
        int n = arr.size();
        double sum = 0;
        int cnt = 0;
        for(int i = n/20; i<n-n/20; ++i){
            sum += arr[i];
            cnt++;
        }
        return sum/cnt;
    }
};

代码 3,学生分数的最小差值,代码见下

cpp 复制代码
class Solution {
    void insertionSort(vector<int>& a){
        for(int i=1; i<a.size(); ++i){
            int x = a[i];
            int j;
            for(j=i-1; j>=0; --j){
                if(x < a[j]){
                    a[j+1] = a[j];
                }else{
                    break;
                }
            }
            a[j+1] = x;
        }
    }
public:
    int minimumDifference(vector<int>& nums, int k) {
        insertionSort(nums);
        int ret = 100000000;
        for(int i=0; i + k - 1 < nums.size(); ++i){
            int l = i;
            int r = i + k - 1;
            ret = min(ret, nums[r] - nums[l]);
        }
        return ret;
    }
};
相关推荐
paeamecium10 小时前
【PAT甲级真题】- Student List for Course (25)
数据结构·c++·算法·list·pat考试
Book思议-10 小时前
【数据结构】栈与队列全方位对比 + C 语言完整实现
c语言·数据结构·算法··队列
是苏浙12 小时前
初识集合框架
java·数据结构
如何原谅奋力过但无声13 小时前
【chap11-动态规划(上 - 基础题目&背包问题)】用Python3刷《代码随想录》
数据结构·python·算法·动态规划
小王C语言14 小时前
【基础IO】————简单设计一下libc库
前端·数据结构·算法
_日拱一卒14 小时前
LeetCode:滑动窗口的最大值
数据结构·算法·leetcode
老约家的可汗15 小时前
list 容器详解:基本介绍与常见使用
c语言·数据结构·c++·list
Book思议-15 小时前
【数据结构】字符串模式匹配:暴力算法与 KMP 算法实现与解析
数据结构·算法·kmp算法·bf算法
mifengxing15 小时前
力扣HOT100——(1)两数之和
java·数据结构·算法·leetcode·hot100
罗湖老棍子15 小时前
【 例 1】区间和(信息学奥赛一本通- P1547)(基础线段树和单点修改区间查询树状数组模版)
数据结构·算法·线段树·树状数组·单点修改 区间查询