/*
單位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
在這裏插入代碼片