[算法教程] 几种经典排序的实现 @blibili正月点灯笼
选择排序:
对于一个乱序数组(size=n)
1.寻找其中的最大(小)值
2.放到最右边(和最后一位交换位置)
3.再从原数组size=n-1同样寻找最大值(此时这个是整个数组第二大的值了(如果有两个相同最大值不影响))
4.继续放到在size=n-1的最右处
5.一直循环到size=1结束排序
数据举例:
3 7 4 2 6 1 (size = 6)
遍历第一遍,找到max = 7;放到最右边,此时:
3 1 4 2 6 7 -->我们需要的是 3 1 4 2 6(size = 5)
遍历,找到max = 6;放到最右边(当然6本来就在最右边,操作后仍不变),此时:
3 1 4 2 6 --> 3 1 4 2(size = 4)
遍历,找到max = 4;放到最右边
3 1 2 4 --> 3 1 2 (size = 3)以此类推
代码实现:
#include<stdio.h>
#include<iostream>
using namespace std;
void selection_sort(int *arr,int n);
int findmax(int *arr,int n);
void swap(int *a,int *b);
int main(){
int arr[]={1,3,4,5,7,3,88,44,23,9};
int n = 10;
selection_sort(arr,n);
for(int i = 0;i<n;i++){
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
int findmax(int *arr,int n){
int max = arr[0];
int maxpos = 0;
for(int i = 0;i<n;i++){
if(arr[i]>max){
max = arr[i];
maxpos = i;
}
}
return maxpos;
}
void swap(int &a,int &b){
int temp = a;
a = b;
b = temp;
}
void selection_sort(int *arr,int n){
int pos;
while(n){
pos = findmax(arr,n);
swap(arr[pos],arr[n-1]);
n--;
}
}
插入排序
对于一个乱序数组(size = n)
假设其数组左侧已经有一定先后顺序了(这样更便于理解)
3 6 7 4 2 1 5,左侧3 6 7已经排好序了,此时对4进行操作
保存4的值为key = 4,以及位置pos = 3(起点)
然后和已经排好序的数组倒序对比,此时对比的size = 4,即
3 6 7 4
arr[pos-1](7)和key(4)对比,显然前者大,所以将7放到pos的位置上,此时数组为
3 6 7 7
不要担心,4的值还保存在key中,让pos-1,继续操作
arr[pos-1](6)和key(4)对比,依然前者大,同样操作,此时数组为
3 6 6 7,继续pos-1
此时arr[pos-1](3)和key(4)对比,key大,那么可以跳出循环了,此时令arr[pos] = key,那么数组就变为
3 4 6 7,插入成功
补充:如
3 4 6 7 2这样,当2一直遍历到pos=0的时候依然没有可以插入的位置,这时候再继续下去会造成数组越界,所以当pos=0就应该break出去。
代码实现:
#include<stdio.h>
#include<iostream>
using namespace std;
void insertion_sort(int *arr,int n);
int main(){
int arr[]={1,3,4,5,7,3,88,44,23,9};
for(int i = 1;i<10;i++){
insertion_sort(arr,i);
}
for(int i = 0;i<10;i++){
printf("%d ",arr[i]);
}
return 0;
}
void insertion_sort(int *arr,int n){
int key = arr[n];
int i = n;
while(arr[i-1]>key){
arr[i] = arr[i-1];
i--;
if(i==0)
break;
}
arr[i] = key;
}