常用排序算法(快速排序、选择排序、直接插入排序)

对数组进行排序

Given an array of integers nums, sort the array in ascending order.

Example 1:

Input: nums = [5,2,3,1]
Output: [1,2,3,5]
Example 2:

Input: nums = [5,1,1,2,0,0]
Output: [0,0,1,1,2,5]

在leetcode上练习了一些与数组相关的题目,之前用到排序的时候都是直接调用STL中的算法,这次自己实现一下排序的算法。分别使用:快速排序(代码简洁)、简单选择排序(代码简短)、直接插入排序、堆排序。

题意:此题可以使用多种排序算法进行解答,算是数据结构中的基础题目。
方法:分别尝试使用简单选择排序、直接插入排序、快速排序方法来解决,但是由于简单选择排序和直接插入排序的时间复杂度比较高,没有通过所有的测试用例。

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        
        // selectSort(nums);
        // insertSort(nums);
        // quickSort(nums,0,nums.size()-1);
        // bubbleSort(nums);
        heapSort(nums);
        return nums;
        
    }

    // 简单选择排序
    void selectSort(vector<int>& nums){
        // 1.使用选择排序,由于时间复杂度为N方,测试用例通过率为9/10.
        
        int i,j;
        int selected,temp;
        for(i=0;i<nums.size()-1;i++){
            selected = nums[i];
            for(j=i;j<nums.size();j++){
                if(selected>nums[j]){
                    temp = selected;
                    selected = nums[j];
                    nums[j] = temp;
                }
            }
            nums[i] = selected;
        }
    }

    // 直接插入排序
    void insertSort(vector<int>& nums){
        // 2.使用直接插入排序,也是由于时间复杂度为N方,测试用例通过了9/10
        int i,j,k;
        int temp;
        for(i=1;i<nums.size();i++){
            for(j=i-1;j>=0;j--){    // 为元素a[i],在前面找到合适的插人位置(j的后面)
                if(nums[j]<nums[i]){
                    break;
                }
            }
            if(j != i-1){
                // 将比a[i]大的数向后移
                temp = nums[i];
                for(k=i-1;k>j;k--){  
                    nums[k+1] = nums[k];
                }
                nums[j+1] = temp;   //将a[i]放到j的后面。
            }
            
        }
    }

    // 快速排序
    void quickSort(vector<int>& nums,int l,int h){
            if(l < h){
                int pivot = nums[l];
                int i = l,j = h;
                while(i < j){
                	// 从后向前找比pivot小的数。
                    while(i<j && nums[j]>pivot){
                        j--;
                    }
                    if(i<j)	
                        nums[i++] = nums[j]; 
                    // 从前往后找比pivot大的数。
                    while(i<j && nums[i]<pivot){
                        i++;
                    }
                    if(i<j)
                        nums[j--] = nums[i];
                }
                // 最后将pivot的值放到分割点上
                nums[i] = pivot;
                // 分治递归排序
                quickSort(nums,l,i-1);
                quickSort(nums,j+1,h);
            }
        }

    // 冒泡排序
    void bubbleSort(vector<int>& nums){
        // 时间复杂度同样为N方,只有9/10的用例通过
        for(int i=0;i<nums.size()-1;i++){   // 比较的趟数
            for(int j=0;j<nums.size()-i-1;j++){ // 每一趟中比较的次数
                if(nums[j]>nums[j+1]){
                    int temp = nums[j];
                    nums[j] = nums[j+1];
                    nums[j+1] = temp;
                }
            }
        }
    }

    // 堆排序
    void heapSort(vector<int>& nums){
        // 时间复杂度与快速排序相同,测试用例都可以通过
        int len = nums.size();
        heapBuild(nums,len);
        for(int newLen=len-1;newLen>0;newLen--){   
            swap(nums,newLen,0);
            // heapBuild(nums,newLen);
            heapAdjust(nums,0,newLen);
        }
    }
    // 建立大顶堆
    void heapBuild(vector<int>& nums,int len){
        for(int i=len/2-1;i>=0;i--){    // 从最后一个非叶结点开始调整
            heapAdjust(nums,i,len);
        }
    }
    // 调整大顶堆
    void heapAdjust(vector<int>& nums,int i,int end){
        int ded = i;
        int son = 2*i + 1;
        int largest = ded;
        if(son < end && nums[largest] < nums[son])
            largest = son;
        if(son+1 < end && nums[largest] < nums[son+1])
            largest = son + 1;
        if(largest != i){
            swap(nums,largest,i);
            heapAdjust(nums,largest,end);
        }
    }
    // 交换两个位置上的值
    void swap(vector<int>& nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
};

关于堆排序:其思想是使用数据结构中的堆来实现。
算法描述描述 :

  1. 将待排序的关键字序列{R1,R2,R3,…Rn}构建为一个大顶堆,此时R1为最大值。
  2. 将R1与最后一个元素交换位置,{R1,R2,R3…Rn-1}是一个无序序列,此时{R1,R2,R3…Rn-1} \leq{Rn}
  3. 这个时候R1违反了大顶堆的定义,要对R1进行调整,让{R1,R2,R3…Rn-1}构成大顶堆,将R1与Rn-1交换位置,此时无序序列{R1,R2,R3…Rn-2}\leq有序序列{Rn-1,Rn}
  4. 重复此过程,当有序序列中有n-1个元素时,排序完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章