选择,快速,希尔,堆排序为不稳定排序,插入,冒泡,归并,基数排序为稳定排序。
插入排序:
将数据分为有序部分和待排序部分,每次将待排序部分的第一个元素在有序部分中找到插入的位置,并将其插入。
for(int i=1;i<length;i++){
for(int j=i-1;j>=0;j--){
if(data[j]>data[j+1]){
swap(data[j],data[j+1]);
}
else{
break;//没有发生交换说明有序,直接跳出
}
}
}
希尔排序:
先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量,在每组中再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
void shellSort(int a[],int len)
{
int step;
int i,j;
int temp;
for(step=len/2; step>0;step/=2) //用来控制步长,最后递减到1
{
// i从第step开始排列,应为插入排序的第一个元素
// 可以先不动,从第二个开始排序
for(i=step;i<len;i++)
{
temp = a[i];
for(j=i-step;(j>=0 && temp < a[j]);j-=step)
{
a[j+step] = a[j];
}
a[j+step] = temp; //将第一个位置填上
}
}
}
冒泡排序:
相邻元素两两比较,每趟交换以后的最后一个位置就是最大的。
for (int i = 0; i < length - 1; i++) {
bool swapped = false;
for (int j = 0; j < length - i - 1; j++) {
if (data[j] > data[j + 1]) {
swap(data[j], data[j + 1]);
swapped = true;
}
}
if (swapped == false) {
break; //一趟比较没有发生交换说明有序,直接跳出
}
}
快速排序:
每次选取待排序区间的第一个元素作为基准记录,之后将整个区间分为两部分,小于基准的部分和大于基准的部分,之后递归处理两个区间。
void quick_sort(int l,int r){
if(l>r)
return ;
int pivot=data[l], i=l, j=r;
while(i<j){
while(i<j&&data[j]>=pivot){//找到小于基准的元素
j--;
}
while(i<j&&data[i]<=pivot){//找到大于基准的元素
i++;
}
if(i<j){
swap(data[i],data[j]);
}
}
swap(data[l],data[i]);
quick_sort(l,i-1);
quick_sort(i+1,r);
}
选择排序:
每趟操作将待排序部分最小的元素放再待排序部分的最前面。可以直接通过待排序部分第一个元素和待排序部分所有元素的交换来实现。
for(int i=0;i<length-1;i++){
for(int j=i+1;j<length;j++){
if(data[i]>data[j]){
swap(data[i],data[j]);
}
}
}
归并排序:
借用一个数组,将两个有序部分归并,每次从两个有序部分中取出最小的元素放入数组中。
void merge_sort(int l, int r) {
if (l == r) {
return; //只有一个元素
}
int mid = (l + r) / 2;
merge_sort(l, mid);
merge_sort(mid + 1, r);
int x = l, y = mid + 1,
loc = l; // x,y为两个有序区间待选取元素的下标,loc为数组待插入的下标
while (x <= mid || y <= r) { //当两个有序部分还有元素
if (x <= mid && (y > r || data[x] <= data[y])) {
temp[loc] = data[x];
x++;
} else {
temp[loc] = data[y];
y++;
}
loc++;
}
for (int i = l; i <= r; i++) {
data[i] = temp[i]; //将原数组变为有序
}
}