交换式排序-快速排序
快速排序是一种不稳定排序方法,在元素移动过程中产生了逆序。排序算法的稳定性即,排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。
快速排序用到了递归函数,其时间复杂度为o(nlogn)。
其代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 将给定数组排序
* @param arr int整型vector 待排序的数组
* @return int整型vector
*/
//快速排序
int Partition(vector<int>& arr,int low,int high){
int i,j;
i=low,j=high;
int tmp=arr[i];
do{
while(arr[j]>=tmp&&i<j){
j--; //j向左扫描,直到遇见比arr[0]更小的
}
arr[i]=arr[j];
while(arr[i]<=tmp&&i<j){
i++; //i向右扫描,直到遇见比arr[0]更大的
}
arr[j]=arr[i]; //交换ij
}while(i!=j);
arr[i]=tmp;
return i;
}
void quickSort(vector<int>& arr,int low,int high) {
int i;
if(low<high){
i=Partition(arr,low,high);
quickSort(arr, low, i-1);
quickSort(arr, i+1, high);
}
}
void mySort1(vector<int>& arr) {
quickSort(arr, 0, arr.size()-1);
}
vector<int> MySort(vector<int>& arr) {
// write code here
mySort1(arr);
return arr;
}
};
选择式排序-堆排序
选择式排序的基本思想是:
每一趟从待排序的记录中选出关键字最小或最大的记录,按顺序放在记录序列的最后或最前。
我目前学到的选择式排序(简单选择排序和堆排序)都是不稳定排序,其空间复杂度为o(1),时间复杂度为o(nlogn)。
一般的解决方案
其代码如下(成功ac):
//-----堆排序-----
void Sift(vector<int>& arr,int i,int n){
int left = 2*i + 1; // index的左子节点
int right = 2*i + 2;// index的右子节点
int maxIdx = i;
if(left<n && arr[left] > arr[maxIdx])maxIdx = left;
if(right<n && arr[right] > arr[maxIdx])maxIdx = right;
if(maxIdx != i)
{
swap(arr[maxIdx], arr[i]);
Sift(arr, maxIdx, n);
}
}
void heapSort(vector<int>& arr){
int i;
int n=arr.size();
//把所有的非叶结点都筛选一遍
for(int i=n/2-1;i>=0;i--){
Sift(arr,i,n); //建立初始最大堆
}
for(int i=n-1;i>=1;i--){ //做n-1趟堆排序
swap(arr[0],arr[i]);
Sift(arr,0,i);
}
}
};
遇到的问题
下面一个用循环写的sift函数,思路好像也没毛病,但不知道为什么堆排序的正确率只有80%…修改sift函数为上面的递归以后才能够正确运行:
如果有大神看出来哪里有问题可否指点一下我这个菜TAT。
//-----堆排序-----
void Sift(vector<int>& arr,int i,int n){
int j;
j=i*2+1; //j是i的左儿子
while(j<=n){
if(j<n&&arr[j]<arr[j+1]){
j++; //j是i的右儿子
}
if(j<n&&arr[j]>arr[i]){
swap(arr[i], arr[j]);
i=j; //继续检查下一个儿子
j=i*2+1;
}else break;
}
}
利用STL priority_queue解决
参考链接:
http://c.biancheng.net/view/480.html
priority_queue 实例默认有一个 vector 容器。函数对象类型 less 是一个默认的排序断言,定义在头文件 function 中,决定了容器中最大的元素会排在队列前面。function 中定义了 greater,用来作为模板的最后一个参数对元素排序,最小元素会排在队列前面。当然,如果指定模板的最后一个参数,就必须提供另外的两个模板类型参数。
//-----堆排序-----
void heapSort(vector<int>& arr){
priority_queue<int,vector<int>,greater<int>> q;
for(int i=0;i<arr.size();i++){
q.push(arr[i]);
}
for(int i=0;i<arr.size();i++){
arr[i]=q.top();
q.pop();
}
}
用这种方法似乎速度会比之前一般的自己写堆排序快一些: