基础排序算法(插入、选择、冒泡、快速、归并)

1.插入排序
基本思想:每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
时间复杂度:最坏O(N^2),最好O(N)
空间复杂度O(1)

vector<int> insertionSort9(vector<int>& nums) {
        if(nums.size <= 1)
            return nums;
        for(int i = 1; i < nums.size(); i++)
        {
            int v = nums[i];        //临时变量保存nums[i]的值
            int j = i - 1;            
            while(j >= 0 && nums[j] > v)  //在已排序部分寻找插入位置
            {
                nums[j + 1] = nums[j];
                j--;
            }
            nums[j + 1] = v;
        }
        return nums;
    }

2.选择排序
基本思想:基本思想为每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。
时间复杂度:O(N^2)
空间复杂度:O(1)

   vector<int> sortArray(vector<int>& nums) {
       
       for(int i = 0; i < nums.size() - 1; i++)
       {
           int minNum = i;
           for(int j = i + 1; j < nums.size(); j++)   //从未排序序列中选取最小值,记录最小值位置
           {
               if(nums[j] < nums[minNum])
               {
                   minNum = j;
               }
           }
            int temp = nums[minNum];   
            nums[minNum] = nums[i];
            nums[i] = temp;
       }
       return nums;
   }
};

3.冒泡排序
基本思想:对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。
时间复杂度:O(N^2)
空间复杂度:O(1)

function MySort( arr ) {
    for(let i = 0; i < arr.length - 1; i++)
        {
            let flag = false;
            for(let j = 1; j < arr.length - i; j++)
                {
                    if(arr[j - 1] > arr[j])
                        {
                            [arr[j - 1], arr[j]] = [arr[j], arr[j - 1]];
                            flag = true;
                        }
                }
            if(!flag)
                break;
        }
    return arr
}

4.快速排序
基本思想:选择一个基准,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。快速排序
时间复杂度:O ( nlog2n )

function MySort(arr) {
    //快速排序
    let len = arr.length
    if(len <= 1)
        return arr;
    QuickSort(arr, 0, len - 1);
    return arr;
    
}
function QuickSort(arr, left, right)
{
    let temp = arr[left];
    let i = left;
    let j = right;
    if(i >= j)
        return;
    while(i < j)
        {
            while(i < j && arr[j] >= temp)
                j--;
            while(i < j && arr[i] <= temp)
                i++;
            if(i < j)
                [arr[i], arr[j]] = [arr[j], arr[i]];
        }
    
    arr[left] = arr[i];    //i,j 相遇,填充首位
    arr[i] = temp;        //基准归位
    QuickSort(arr, left, i - 1);
    QuickSort(arr, i + 1, right);
}

5.归并排序
时间复杂度:O ( nlog2n )
1.递归划分。计算数组的中点middle,递归划分左数组:left = nums.slice(0, middle),递归划分右数组:right = nums.slice( middle)。递归终止条件:当数组长度为1时,终止递归。
2.合并。创建辅助数组res,设置指针cur,i,j分别指向res,左,右数组。
1)当i>left.len,左子数组已合并完,只需添加right到res中;
2)当j > right.len, 右子数组已合并完,只需添加left到res中;
3)左右数组均未合并完,比较左右数组值的大小,若左子数组<右子数组,辅助数组中添加左子数组的值;若左子数组 > 右子数组,辅助数组添加右子数组的值。


function MySort(arr) {
    //归并排序
    if(arr.length <= 1)
        return arr;
    let middle = Math.floor(arr.length / 2);
    let left = arr.slice(0, middle);
    let right = arr.slice(middle, arr.length);
    return merge(MySort(left), MySort(right));
    
}
function merge(arr1, arr2){
    let len = arr1.length + arr2.length;
    let res = new Array(len).fill(0);
    let i = 0;
    let j = 0;
    for(let cur = 0; cur < len; cur++)
        {
            if(i >= arr1.length)
                {
                    res[cur] = arr2[j++];
                }
            else if(j >= arr2.length)
                {
                    res[cur] = arr1[i++];
                }
            else if(arr1[i] <= arr2[j])
                {
                    res[cur] = arr1[i++];
                }
            else{
                res[cur] = arr2[j++];
            }
        }
    return res;
}
posted @ 2021-05-14 13:46  张宵  阅读(72)  评论(0编辑  收藏  举报