排序算法理解及其 需要考虑时间消耗


/*
单位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
在这里插入代码片

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