每次写出来都不一样,说明我是人不是机器。
#include<iostream>
#include<vector>
void FastSort(std::vector<int> &arr,int is,int ie){
if(is>=ie)return;
int i(is),j(ie);
int val(arr[i]); //如果要用中间元素arr[(is+ie)/2]那直接和arr[is]交换一下swap(arr[(is+ie)/2],arr[is])
while(i<j){
while(i<j && arr[j]>=val)j--; //跳过等于的,保持稳定
if(i<j){
arr[i]=arr[j];
i++;
}
while(i<j && arr[i]<=val)i++; //跳过等于的,保持稳定
if(i<j){
arr[j]=arr[i];
j--;
}
}
arr[i]=val;
FastSort(arr,is,i-1); //二分
FastSort(arr,i+1,ie);
return;
}
void GuibinSort(std::vector<int> &arr,int is,int ie){ //归并排序
if(is>=ie)return;
if(is==ie-1){
if(arr[is]>arr[ie]) std::swap(arr[is],arr[ie]);
return;
}
int im((is+ie)/2);
GuibinSort(arr,is,im);
GuibinSort(arr,im+1,ie);
//组装
std::vector<int> arrt(ie-is+1,0);
int i(is),j(im+1),k(0);
while(i<=im && j<=ie){
if(arr[i]<=arr[j])arrt[k++]=arr[i++]; //如果相等则先压左边,保持稳定
else arrt[k++]=arr[j++];
}
if(i>im){ //左边用尽
while(j<=ie)arrt[k++]=arr[j++];
}else if(j>ie){
while(i<=im)arrt[k++]=arr[i++];
}
for(int m(0);m<ie-is+1;m++) arr[is+m]=arrt[m];
return;
}
int main(int argc,char *argv[]){
std::vector<int> arr{3,1,4,1,5,9,2,6};
FastSort(arr,0,arr.size()-1);
for(int i(0);i<arr.size();i++)std::cout<<arr[i]<<" ";
std::cout<<"\n";
std::vector<int> arr2{3,1,4,1,5,9,2,6};
GuibinSort(arr2,0,arr2.size()-1);
for(int i(0);i<arr.size();i++)std::cout<<arr2[i]<<" ";
std::cout<<"\n";
}
编译运行:
VMCatalina:Exception haypin$ clang++ -g fastsort.cpp -std=c++11 -o main
VMCatalina:Exception haypin$ ./main
1 1 2 3 4 5 6 9
1 1 2 3 4 5 6 9
VMCatalina:Exception haypin$
转自《C Concurrent In Action 2nd》4.4.1给出的,使用C++标准库std::partition()函数以序列首元素为基准实现二分原位重排的快排:
#include<iostream>
#include<list>
template<typename T>
std::list<T> FastSort(std::list<T> input){
if(input.empty()) return input;
std::list<T> result;
//1、首先将链表首元素移动到结果链表result
result.splice(result.begin(),input,input.begin());
T const &pivot=*result.begin();
//2、将链表剩下的元素按"小于首元素的放前面,不小于首元素的放后面"原则重排(原位重排)
//,并返回后面部分最前面元素的迭代器
auto divide_point=
std::stable_partition(input.begin(),input.end(),[&](T const& t){return t<pivot;});
std::list<T> lower_part;
//3、移动已经重排过的链表的小于分界值的部分
lower_part.splice(lower_part.end(),input,input.begin(),divide_point);
//4、二分递归排序
auto new_lower(FastSort(std::move(lower_part))); //小于分界值的部分,实参移动到形参而不是拷贝
auto new_higher(FastSort(std::move(input))); //剩下的,分界值之后大于的部分
//5、组装二分重排部分
result.splice(result.end(),new_higher); //分界点之后大于的部分
result.splice(result.begin(),new_lower);
return result;
}
int main(int argc,char *argv[]){
std::list<int> arr{3,1,4,1,5,9,2,6};
arr=FastSort(arr);
std::for_each(arr.begin(),arr.end(),[](int &ele){std::cout<<" "<<ele;});
std::cout<<"\n";
}
编译运行:
HaypinsMBP:MultiThread haypin$ clang++ -g slice.cpp -std=c++11 -o main
HaypinsMBP:MultiThread haypin$ ./main
1 1 2 3 4 5 6 9
HaypinsMBP:MultiThread haypin$
210728补充一个python的归并排序:
#!/usr/bin/env python
#-*- coding: utf-8 -*-
def GuibinSort(data=[],istart=0,iend=0):
if istart >=iend:
return
imid = int((istart+iend)/2)
GuibinSort(data,istart,imid)
GuibinSort(data,imid+1,iend)
arr = []
i = istart
j = imid+1
while i<=imid and j<=iend:
if data[i]<=data[j]: # stable
arr.append(data[i])
i+=1
else:
arr.append(data[j])
j+=1
if i>imid:
while j<=iend:
arr.append(data[j])
j+=1
else:
while i<=imid:
arr.append(data[i])
i+=1
i = istart
while i<=iend:
data[i]=arr[i-istart]
i+=1
return
if __name__ =='__main__':
mylist = [3,1,4,1,5,9,2,6]
GuibinSort(mylist,0,len(mylist)-1)
print(mylist)
运行:
haypin@MBP ~/catkin_ws/src/creeper main python guibinSort.py
[1, 1, 2, 3, 4, 5, 6, 9]