基本排序方法(堆 归并 快排 )

leetcode排序题

https://leetcode.cn/problems/sort-an-array/

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {

    }
};

归并排序

基本思想

分治,然后合并排序。

代码实现

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        
        int n=nums.size();
        //辅助数组
        vector<int> temp(n);
        //调用归并排序
        mergeSort(nums,temp,0,n-1);
        
        return nums;
    }
    
    void mergeSort(vector<int>& nums,vector<int>& temp,int start,int end) {
        
  		if(start<end) {

            int mid=(start+end)/2;
        	mergeSort(nums,temp,start,mid);
            mergeSort(nums,temp,mid+1,end);
            merge(nums,temp,start,mid,end);//合并排序到nums
        }
        
    }
    
    void merge(vector<int>& nums,vector<int>& temp,int start,int mid,int end) {
        
        int i=start,j=mid+1;
        int k=start;
        
        while(i<=mid || j<=end) {
            
            if(nums[i]<=nums[j]) {
           		temp[k]=nums[i];
                k++;
            }
            else {
                temp[k]=nums[j];
                k++;
            }
            
        }
        
        //如果还有没有比较完的
        while(i<=end) {
            temp[k]=nums[i];
            i++;
            k++;
        }
        //如果还没有比较完的
        while(j<=end) {
            temp[k]=nums[j];
            j++;
            k++
        }
        
        for(int i=start;i<=end;i++) {
            nums[i]=temp[k];
        }
        
    }
    
    
}

堆排序

基本思想

考虑[0 1 2 ... n-1]的非排列数组

  • 堆建立

    从底层第一个非叶子节点(n/2-1)开始,调整其节点到合适位置,使子树仍为大顶堆,直到根节点。这个调整函数就设置为head_down()

  • 堆排序

    在堆建立后,每次将根节点与末尾元素进行交换,重新进行head_down进行排序。

代码实现

class Solution {
public :
	
    vector<int> sortArray(vector<int> &nums) {
        
        int n=nums.size();
        
        //建立大顶堆
        MaxHeap(vector<int> &nums,int n);
        
        //堆排序
        for(int i=n-1;i>=0;i--) {
            
            //冒泡
            swap(nums[i],0);
            //重新调整
            Heap_adjust(nums,0,i-1);
        }
    }
    
	//建立大顶堆
    void MaxHeap(vector<int> &nums,int n) {
        //从n/2-1开始
        for(i=n/2-1;i>=0;i--) {
        	Heap_adjust(nums,i,n-1);
        }
    }
    
    void Heap_adjust(vector<int> &nums,int start,int end) {
        
        
        int cur=start;
        int left=cur*2;
        int right=left+1;
        
        //直到左子节点超过end
        while(left<=end) {
           
            int max=i;
           //判断哪个节点最大
           if(nums[left]>nums[max])
           		max=left;
            if(nums[right]>nums[max])
				max=right;
            //不需要再调整
            if(max==cur)
                break;
            
            //交换较大的
            swap(nums[max],nums[cur]);
            cur=max;
            left=cur*2;
            right=left+1;
            
        }
        
        
    }
    
}

快排序

基本思想

  • 从数列中挑出一个元素,称为 "基准",将小于其值的元素放在前面,将大于其值的元素放在其后面。
  • 继续划分,直至只剩一个数。

代码实现

class Solution {
    
public:
	
    vector<int> sortArray(vector<int>& nums) {
        int n=nums.size();
    	quicksort(nums,0,n-1);
        return nums;
    }
    
    void quicksort(vector<int>& nums,int start,int end) {
        
        if(start<end) {
            
            //分区,返回基准元素位置
            int base=splict(nums,start,end);
            //继续排序子分区
            quicksort(nums,start,base-1);
            quicksort(nums,base+1,end);
        }     
    }
    
    int splict(vector<int>& nums,int start,int end) {
        
    	//以start元素作为基准
        int base_value=nums[start];
        
        while(start<end) {
            
            //找到应该放前面的元素
            while(start<end && base_value<=nums[end])
                end--;
           	nums[start]=nums[end];
            //找到应该放在后面的元素
            while(start<end && base_value>=nums[start])
                start++;
            nums[end]=nums[start];
            
        }
        
        return start;
        
    }
    
}
posted @ 2022-08-23 15:07  xfw121  阅读(55)  评论(0)    收藏  举报