数据结构与算法 —— O(nˆ2)排序算法(冒泡,选择,插入)(c++)

https://www.cnblogs.com/BobHuang/p/11263183.html
https://www.jianshu.com/p/9e855ba2b079
https://www.cnblogs.com/onepixel/p/7674659.html

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include <ctime>

using namespace std;


//常见三种低级排序:冒泡,选择,插入



// 冒泡排序
//大数置后,相邻俩俩比较,左边比右边的大就只要大就交换, 每次循环最大的数就会被放到最后
//O(n^2) S(1)
//最好时间复杂度为如果全部完成排序,则一趟就可以判断已经排序O(n)。最差时间复杂度为O(n*(n-1) / 2) = O(n^2)
//由于不会修改前后相等元素的顺序,所以是稳定算法
void BubbleSort(vector<int>& v)
{
    
    
    bool flag = true;
    for (int i = 1; i < v.size(); i++)  // i为总共循环次数, 一共n-1次循环
    {
    
    
        for (int j = 0; j < v.size() - i; j++)  // j表示相邻数,每次循环需要比较的个数,最大数放到后面就是排序好的不计入
        {
    
    
            if (v[j] > v[j + 1]) {
    
    
                swap(v[j], v[j + 1]);  //交换
                flag = false;//如果进行交换则说明还在比较则flag设为false
            }
        }
        //判断此次循环是否排序完成,如果排序完成直接退出
        if(flag) break;
    }
}


// selection sort 选择排序
// 每次循环,选择第一个数和他后面每一个数进行比较,并记录该次循环最小值的下标,然后将最小值放到最前面
// O(n^2) S(1)
//最好、最坏时间复杂度都是O(n^2) 因为每个数都要和后面的数进行比较。适合小规模排序。
//不稳定,因为每次交换不能保证相等的元素顺序
void SelectionSort(vector<int>& v)
{
    
    
    for (int i = 0; i < v.size() - 1; i++)  // i为已排序下标,第一个数到倒数第二个数
    {
    
    
        int minIndex = i;                       //使用临时下标记录每次最小值
        for (int j = i + 1; j < v.size(); j++)  // j来遍历后面未排序的元素
        {
    
    
            if (v[minIndex] > v[j]) {
    
     //当找到小值,不着急交换,而是仅记录下标
                minIndex = j;  //记录最小值下标
            }
        }
        swap(v[i], v[minIndex]);  //都遍历完一趟然后交换,减少交换次数
    }
}

// 插入排序
// O(n^2) S(1)
// 每次挑选一个数,跟他前面的有序序列进行比较,在有序序列中从后往前遍历,如果小于就后移序列,然后插入该数
// 最好时间复杂度,如果排序好的数组,则每次直接break不进行内层循环O(n),最坏时间复杂度O(n^2)
// 稳定,因为比他不会交换相等两数的位置
void InsertionSort(vector<int>& v)
{
    
    
    for (int i = 1; i < v.size(); i++)  // i遍历未排序数组,从第二个数开始,第一个数认为i是有序序列
    {
    
    
        int cur = v[i];
        int j = i - 1;
        while(j >= 0) {
    
     // j遍历已排序数组(从后往前)
            //如果当前数小于排序数组中的元素,则后移该排序数组元素
            if (cur < v[j])  {
    
    
                v[j + 1] = v[j];  // 后移该数
            }
            else {
    
    //如果当前数大于遍历到的数,将cur放入然后跳出
                break;
            }
            j--;
        }
        v[j+1] = cur;
    }
}

int main()
{
    
    
    //随机产生N个数
    int N = 20000;
    srand(time(NULL));  //生成随机数种子
    //放到vector中
    vector<int> nums(N);
    for (int i = 0; i < N; ++i) {
    
    
        nums[i] = 1 + (rand() % N);
        //cout << nums[i] << ",";
    }
    cout << endl;
    //开始计时
    double start, finish; /* 定义开始的时间和结束的时间 */
    start = (double)clock();


    //BubbleSort(nums); //2288ms
    //SelectionSort(nums); //915ms
    //InsertionSort(nums); //528ms


    finish = (double)clock();
    //打印
    // for (auto item : nums)
    // {
    
    
    //     cout << item << ",";
    // }
    
    cout << (finish) - start << " ms" << endl;

}

猜你喜欢

转载自blog.csdn.net/chongbin007/article/details/105669451