十大排序总结

十大排序

1、冒泡排序

理论分析

冒泡排序是一种简单直观的排序算法。重复走访要排序的元素,每次两两对比,并进行交换。

实现

双层循环,其中内存循环一次比较相邻元素,逐渐将最边缘的数字移到最后一个位置。然后外层循环倒序遍历,最终完成排序

#include <iostream>
#include<variant>
#include<vector>
#include "User.h"
using namespace  std;
void bubbile_sort(vector<int>& nums){
    for(int j = nums.size()-1;j>=0;j--){
        for(int i =1;i<nums.size();i++){
            if(nums[i]<nums[i-1]) swap(nums[i],nums[i-1]);
        }
    }
}
int main() {
//    using std::variant;
    std::cout << "Hello, World!" << std::endl;
    User u1("xiaoha",12);
//    std::cout<<u1.get_name()<<std::endl;
    vector<int> vec={1,3,2,5,7,8,5};
    bubbile_sort(vec);
    for(auto c:vec) cout<<c<<endl;
    return 0;
}

2、选择排序

理论分析

是一种简单直观的排序算法,无论什么数据进入,都是o(n2)的时间复杂度。因为都是在内层循环中找最大值,然后交换到最后一个

实现

内层循环遍历当前所有元素,选择出最大的元素,和当前最后一个元素进行交换,然后外层循环依次缩小范围,最终完成排序

#include <iostream>
#include<variant>
#include<vector>
#include "User.h"
using namespace  std;
void bubbile_sort(vector<int>& nums){
    for(int j = nums.size()-1;j>=0;j--){
        for(int i =1;i<nums.size();i++){
            if(nums[i]<nums[i-1]) swap(nums[i],nums[i-1]);
        }
    }
}
void Selection_sort(vector<int>& nums){
    for(int i = nums.size()-1;i>=0;i--){
        int max=0;
        for(int j=0;j<=i;j++){
            max = max<nums[j]? nums[j]:max;

        }
        swap(nums[i],max);

    }
}
int main() {
//    using std::variant;
    std::cout << "Hello, World!" << std::endl;
    User u1("xiaoha",12);
//    std::cout<<u1.get_name()<<std::endl;
    vector<int> vec={1,3,2,5,7,8,5};
//    bubbile_sort(vec);
    Selection_sort(vec);
    for(auto c:vec) cout<<c<<endl;
    return 0;
}

3、插入排序

理论分析

工作原理主要为从前到后构建有序数列,对于未排序的数据,在已排序的序列中从后到前扫描,找到插入位置

实现

需要注意的是,插入排序比本身不是交换数据,而是制造插入的空格。随意在判断有序数据中的位置时,数据要以此后移,制造空位,然后将无序数据放进去

void Insert_sort(vector<int>& nums){
    for(int i=0;i<nums.size();i++){
        int pre = i-1;
        int cur_val = nums[i];
        while(pre>0&&cur_val<nums[pre]){
            nums[pre+1] = nums[pre];
            pre--;
        }
        nums[pre+1]=cur_val;
    }
}

4、希尔排序

理论分析

希尔排序是插入排序的改进版本,为非稳定排序算法。

实现

5、归并排序

理论分析

归并排序和选择排序一样,不受输入数据的影响,时间复杂度始终为o(nlogn),但是需要使用额外空间

实现

思路主要为,通过递归将数组分为只有两个元素,然后定义左右指针,进行对比,并通过中间数组转存,最后再替代原数组。

void merge(int* vec,int len){
    int s = 0;
    int left=0;
    int mid = len/2;
    int right = mid;
    int* arr = new int[len];
    while(left<mid&&right<len){
        if(vec[left]<vec[right]){
            arr[s++]=vec[left++];
        }
        else{
            arr[s++]=vec[right++];
        }
    }
    while(left<mid){
        arr[s++] = vec[left++];
    }
    while(right<len){
        arr[s++] = vec[right++];
    }
    for(int i=0;i<len;i++){
        vec[i]= arr[i];
    }
    delete []arr;
}
void merge_sort(int* vec,int len){
    if(len<2) return ;

    merge_sort(vec,len/2);
    merge_sort(vec+len/2,len-len/2);
    merge(vec,len);
}
int main() {

    int arr[] = {1,3,2,5,7,8,2};

    int a = sizeof(arr);
    int b = sizeof(arr[0]);
    int n = sizeof(arr)/sizeof(arr[0]);
    merge_sort(arr,n);
    for(int i=0;i<n;i++){
        cout<<arr[i]<<endl;
    }
    return 0;
}
需要注意的是,求int数组大小需要使用sizeof(arr)/sizeof(arr[0);

6、快速排序

理论分析

该算法输入的是数组,左节点和右节点。
总体而言是一种分而治之的思想,通过保存一个基准,然后在首尾指针依次对比基准数据,使得左边数据都比基准小,右边数据都比基准大,然后再left=right处插入基准,并将左右不分送入递归

实现

int partion(int vec[],int left,int right){
    int index = vec[left];
    while(left<right){
        while(left<right&&vec[right]>=index) right--;
        vec[left]=vec[right];

        while(left<right&&vec[left]<=index) left++;
        vec[right]=vec[left];



    }
    vec[left]=index;
    return left;
}
void quick_sort(int vec[],int left,int right){
    if(left<right){
        int mid = partion(vec,left,right);
        quick_sort(vec,left,mid-1);
        quick_sort(vec,mid+1,right);
    }
}

7、堆排序

理论分析

堆的本质是完全二叉树,即根节点的数值一定比叶子结点大,但不保证层序遍历有序。
且当有n个二叉树结点时,n/2为最大的非叶子结点序号
每次交换最大节点之后,递归的判断换下去的字数是否为堆

实现

在选择最大值时,每次将最大值放到数组最后,然后通过heapify函数调整交换点一下的顺序,然后缩小边界,所以直接用heapify(vec,0,i)

void heapify(int vec[],int i,int len){
        int left = i*2+1;
        int right = i*2+2;
        int max = i;
        if(left<len&&vec[left]>vec[max]){
            max = left;
        }
        if(right<len&&vec[right]>vec[max]){
            max = right;
        }
        if(max!=i){
            swap(vec[i],vec[max]);
            heapify(vec, max, len);
        }



}
void heap_sort(int vec[],int len){
    for(int i=len/2-1;i>=0;i--){
        heapify(vec,i,len);
    }
    for(int j=len-1;j>0;j--){
        swap(vec[0],vec[j]);
        heapify(vec,0,j);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值