基本排序方法(堆 归并 快排 )
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;
}
}

浙公网安备 33010602011771号