C++编程:常用排序算法
冒泡排序
算法思想:
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
void mySort(vector<int>& nums){
if(nums.size()<2){
return;
}
for(int i = 0; i<nums.size()-1; i++){
for(int j = 0; j<nums.size()-1-i; j++){
if(nums[j] > nums[j+1]){ //升序 (降序的话换成<即可)
swap(nums[j], nums[j+1]);
}
}
}
}
选择排序
算法思想:
选择排序(Selection-sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
//下面有问题但是还没有排查出来
void mySort(vector<int>& nums){
if(nums.size()<2){
return;
}
int minNum;//这里用下标,直接保存数值的话会出错
int tmp;
for(int i=0; i<nums.size()-1;i++){ //注意i不取最后一个,因为j是i后面的
minNum = i;
for(int j=i+1; j<nums.size();j++){
if(nums[j] < nums[minNum]){
minNum = j;
}
}
swap(nums[minNum], nums[i]);
}
}
插入排序
算法思想:
通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。一般认为第一个数据是有序的。
void mySort(vector<int>& nums){
if(nums.size()<2){
return;
}
int preIndex;//记录有序数组的最后一个下标
int current;
for(int i=1; i<nums.size();i++){
preIndex = i-1;
current = nums[i];
while(preIndex>=0 && nums[preIndex]>current){
nums[preIndex+1] = nums[preIndex];
preIndex--;
}
nums[preIndex+1]=current;
}
}
希尔排序
算法思想:
第一个突破O(n2)的排序算法,是简单插入排序的改进版。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序又叫缩小增量排序。
//时间原因,还没有看懂呢
void mySort(vector<int>& nums){
if(nums.size()<2){
return;
}
for(int gap=nums.size()/2; gap>0; gap=gap/2){
for(int i=gap; i<nums.size(); i++){
int j = i;
int current = nums[i];
while(j-gap>=0 && current<nums[j-gap]){
nums[j] = nums[j-gap];
j = j-gap;
}
nums[j] = current;
}
}
}
归并排序
算法思想:
该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,速度仅次于快速排序。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。
//使用了tmp保存结果
void mySort(vector<int>& nums,int begin,int end,vector<int>& tmp){
if(begin == end){
return;
}
int mid = (begin+end)/2;
mySort(nums, begin, mid, tmp);
mySort(nums, mid+1, end, tmp);
int i = begin;
int j = mid+1;
int s = begin;//s指向临时结果数组
// 比较两个有序小数组的元素,依次放入大数组中
while (i <= mid && j <= end) {
if(nums[i] < nums[j]){
tmp[s++] = nums[i++];
}
else{
tmp[s++] = nums[j++];
}
}
// 右侧小数组已排序完毕,左侧小数组还有剩余,将左侧小数组元素依次放入大数组尾部
while (i <= mid) {
tmp[s++] = nums[i++];
}
// 左侧小数组已排序完毕,右侧小数组还有剩余,将右侧小数组元素依次放入大数组尾部
while (j <= end) {
tmp[s++] = nums[j++];
}
}
快速排序
//快速排序
void func(vector<int>& nums,int begin,int end){
if(begin < end){
int tmp = nums[begin];//选择基准,一般选择第一个作为基准
int i = begin;
int j = end;//j指向最右边的元素
while (i < j) {
//nums[j]小于tmp的话才需要移动
while (i<j && nums[j] >= tmp) {
j--;
}
nums[i] = nums[j];
//nums[i]大于tmp的话才需要移动
while (i<j && nums[i] <= tmp) {
i++;
}
nums[j] = nums[i];
}
nums[i] = tmp;
func(nums,begin,i-1);
func(nums,i+1,end);
}
}
快速排序算法参考
归并排序算法参考
十大排序算法参考