/*
单位us
选择排序 time:183162
插入排序 time:835829
优化后的插入排序(1): time:385136
优化后的插入排序(2(for循环直接比较)): time:309751
ShellSort time:439316
OptimizeShellSort(for循环直接比较) time:4558
*/
#include <iostream>
#include <vector>
#include <chrono>
#include<sys/time.h>
using namespace std;
/*
给你一个整数数组 nums,请你将该数组升序排列。
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
选择排序:
下面考虑一个选择排序的方法,但是在数组很大的情况下,这样的时间复杂度o(n^2)会很慢。
*/
vector<int> sortArray(vector<int>& nums) {
for(int i = 0; i < nums.size();i++){
int min = nums[i];
int minIndex = i;
for(int j = i+1; j < nums.size(); j++){
if(nums[j] < min){
min = nums[j];
minIndex = j;
}
}
swap(nums[minIndex], nums[i]);
}
return nums;
}
/*插入排序:
假设i前面的序列是排好序的,然后从i+1开始和i进行比较,如果小于i,则说明这个值需要插入到前面的序列中
此时依次倒数和前面的序列比较,如果小于前面一个值,则将这个值和前面的值交换,也就把前面的序列往后移动了
直到发现这个值大于前面的某个值,此时不需要在移动了,此时就是插入到这个位置即可。*/
void InsertSort(vector<int> &nums){
for(int i = 0; i < nums.size();i++){
for(int j = i+1; j < nums.size();j++){
if(nums[j]<nums[i]){
for(int k = j;k >0;k--){
if(nums[k]<=nums[k-1]){
swap(nums[k],nums[k-1]);
}
}
}
}
}
}
/*优化版的插入排序
这个的思想就是从i=1位置开始,把前面排好序的从尾倒数(从i-1开始)两两比较。
如果后面的数据小于前面的数据则交换,否则就遍历即可,不需要交换数据。这样比较晚一轮后。i自增,在进行一轮,直到i增加完
为什么可以做到,是因为前面的序列都是排好序的,所以只要后面的数据比前面的小,则就把后面的数据一个一个往前插入。
*/
vector<int64_t> InsertOptimizeSort(vector<int64_t> &nums){
/*从i=1开始,当然也可以从0开始,只是从1开始便于理解,不停的往后移动*/
for(int i = 0; i< nums.size();i++){
/*然后从i-1开始将j+1&j向前比较,如果j+1位置<j位置,交换位置(其实就是将小的数据往前插入)*/
for(int j = i-1; j>=0;j--){/*向前比较所有的已经排序好的序列的值*/
if(nums[j+1] < nums[j]){/*这里就是插入*/
swap(nums[j],nums[j+1]);
}
}
}
return nums;
}
/*shell排序
希尔排序就是将一个无序数组按照不同的Gap分组,然后对每个分组进行插入排序的过程
*/
vector<int64_t> ShellSort(vector<int64_t> &nums){
for(int gap = nums.size(); gap > 0; gap /=2){
for(int i = gap; i < nums.size(); i++){
for(int j = i; j-gap >=0; j-=gap){
if(nums[j] <nums[j-gap]){ /*这里这个比较放在上面for循环中比较会跟节省时间,如下优化后的,执行时间会缩短很多*/
swap(nums[j],nums[j-gap]);
}
}
}
}
return nums;
}
vector<int64_t> OptimizeShellSort(vector<int64_t> &nums){
for(int gap = nums.size(); gap > 0; gap /=2){
for(int i = gap; i < nums.size(); i++){
/*这里把比较放在for循环处时间上会快100倍:
ShellSort time:439316 us
OptimizeShellSort time:4558 us*/
for(int j = i; j-gap >=0 && nums[j] <nums[j-gap]; j-=gap){/*这里的比较其实就是运用了插入比较的优化点,根据每组gap从尾(j=i=gap处)向前插入*/
swap(nums[j],nums[j-gap]);
}
}
}
return nums;
}
uint64_t GetUs()
{
struct timeval time;
gettimeofday(&time, NULL);
uint64_t timeSec = time.tv_sec;
uint64_t microSeconds = 1000000 * timeSec + time.tv_usec;
return microSeconds;
}
int main(){
int64_t array[]={5864,-12333,4151,-6239,-10306,10866};
vector<int64_t> a;
cout<<"arrya:"<<sizeof(array)/sizeof(array[0])<<endl;
for(uint64_t i = 0; i < sizeof(array)/sizeof(array[0]);i++){
a.push_back(array[i]);
}
/*a.push_back(5);
a.push_back(1);
a.push_back(-1);
a.push_back(2);
a.push_back(0);
a.push_back(0);*/
//vector<int> b;
uint64_t start = GetUs();
OptimizeShellSort(a);
uint64_t end = GetUs();
cout<<"time:"<<end-start<<endl;
cout<<"b.size():"<<a.size()<<endl;
/*for(uint64_t i = 0; i < a.size();i++){
cout<<a[i]<<" ";
}*/
cout<<endl;
}
```cpp
在这里插入代码片