排序算法理解及其 需要考慮時間消耗


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章