五种排序算法(选择、冒泡、归并、快排、插入)的思路和代码。

选择排序

**第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。**以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
–《百度百科》

伪代码:(注意是伪代码,源码在最后!)
void select_sort( *array, size){
    for i=1 to size
        min = i;          //min记录最小值下标
        for j=i to size
            if(array[min]>array[j])
               min = j;
        }
        swap(array[i],array[min]);
}

举例: 34 56 23 65 77 90 12 56
第一轮:(12)(34 56 23 65 77 90 56)
第二轮:(12 23)(34 56 65 77 90 56)
第三轮:(12 23 34)(56 65 77 90 56)
第四轮:(12 23 34 56)(65 77 90 56)
第五轮:(12 23 34 56 56)(65 77 90)

冒泡排序

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
    –《百度百科》

伪代码:

伪代码:(注意是伪代码,源码在最后!)
void bubble_sort(*array, size){
    for i=0 to size
        for j=1 to size-i
            if(array[j-1]>array[j])
               swap(array[j-1],array[j]);
}

举例: 34 56 23 65 77 90 12 56
第一轮: 34 23 56 65 77 12 56 90
第二轮: 23 34 56 65 12 56 77 90
第三轮: 23 34 56 12 56 65 77 90
第四轮: 23 34 12 56 56 65 77 90
第五轮: 23 12 34 56 56 65 77 90
······

归并排序

  1. 将序列上每相邻的两个数字进行排序,
  2. 排序后的n/2 个有序序列每相邻的两个序列进行归并
  3. 重复步骤2,直到整个序列有序。
伪代码:(注意是伪代码,源码在最后!)
void merge_sort( *array,start,end, *result){
    switch(end - start){
        case 1: //只剩两个元素,直接比较排序
               if(array[start]>array[end])
                  swap(array[start],array[end]);
              returncase 0://只剩一个元素,已有序,直接返回
              returndefault
              merge_sort(array,start,(end - start +1)/2+start,result);
              merge_sort(array,(end-start+1)/2+start+1,end,result);
              //合并
              merge(array, start, end, result); //merge函数是自定义的合并两个有序序列的操作
              for i = start to end+1 
                  array[i] = result[i]; 
    }
}
void merge( *array, start, end, *result,){
    //归并,两个有序序列的合并 
     left_length = (end - start + 1) / 2 + 1;    
     left_index = start;
     right_index = start + left_length;
     result_index = start;
    while(left_index<right_index && right_index <end + 1){
        if(array[left_index] <= array[right_index])
            result[result_index++] = array[left_index++];       
        else
            result[result_index++] = array[right_index++];        
    }
    //剩余元素续接在后   
    while(left_index < right_index)
        result[result_index++] = array[left_index++];   
    while(right_index <end+1)
        result[result_index++] = array[right_index++];
}

举例: 34 56 23 65 77 90 12 56
递归逻辑:
Merge_sort(34 56 23 65) Merge_sort(77 90 12 56) //递归进入下一层
Merge_sort(34 56 )Merge_sort (23 65) Merge_sort(77 90)Merge_sort(12 56)//当括号内只有1或2个数时,递归触底。
Merge((34 56) (23 65)) Merge((77 90) (12 56)) //合并已排序列,从头开始,找出较小者。
Merge((23 34 56 65) (12 56 77 92)) //合并已排序列
(12 23 34 56 56 65 77 92)

快速排序

快速排序(Quicksort)是对冒泡排序算法的一种改进。
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
–《百度百科》

伪代码:(注意是伪代码,源码在最后!)
void QSort(*array, size, low, high){
    //快速排序,递归方法 
    if(low<high)
    {
        pivotloc = Partition(array,size,low,high);//Partition()函数返回关键字快排一次后的位置
        QSort(array,size,low,pivotloc-1);
        QSort(array,size,pivotloc+1,high);
    }
} 

int Partition( *array, size, low, high){
    //排序一次,找到枢轴所在位置
     key=array[low]; //记录关键字,待排序列第一个数字作为关键字
    while(low<high){
        while(low<high && array[high]>=key)
            --high; 
        array[low] = array[high];
        while(low<high && array[low]<=key)
            ++low;
        array[high] = array[low];
    } 
    array[low] = key;
    return low;
}

举例: 34 56 23 65 77 90 12 56

第一次Partion:key = 34 //黑色加粗是数值发生改变,() 是枢轴位置。
12 56 23 65 77 90 (12) 56 //
12 (56) 23 65 77 90 56 56
12 23 (23) 65 77 90 56 56 // 枢轴的值比它后面的值都小,无插入,循环结束,修改枢轴位置的值为关键字的值
【12 23】 34 【65 77 90 56 56 】 //可以看到,枢轴进行跳转后,原来位置的值将会进行改变。
对【】内重复排序,最终得到有序序列。
过程略,自行推导。

插入排序

将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表

void insert_sort( *array, size){
伪代码:(注意是伪代码,源码在最后!)
    for i=1 to size
        if(array[i]<array[i-1]){
            key = array[i]; //记录关键字key
            j=i-1;
            while(j>0 && array[j]>key)
                array[j+1]=array[j--]; //数据后移,空出插入位置
        }
        array[j+1]=key; //将关键字插入空位
}

总结

在这里插入图片描述
效率: 插入>选择>冒泡

在这里插入图片描述
快排>归并,因为快排开销更小

举例: 34 56 23 65 77 90 12 56
第一轮: (34) (56 23 65 77 90 12 56)
第二轮: (34 56) (23 65 77 90 12 56)
第三轮: (23 34 56) (65 77 90 12 56)
第四轮: (23 34 56 65) (77 90 12 56)
第五轮: (23 34 56 65 77) (90 12 56)
……

//源码
#include<iostream>
#include<stdlib.h> 
#include "cstring"
#include<time.h>
#include <fstream>   
using namespace std;

void delay(){
	for(int i =0;i<1e8;i++);{
	   for(int j=0;j<1e9;j++);
	   }
	for(int i =0;i<1e8;i++);{
	   for(int j=0;j<1e9;j++);
	   }
} 

int * createTestData(int size){
	//创建随机数组
	srand((int)time(0));
	int* array;
	array = new int [size];
	for(int i = 0;i < size; i++ ){
        array[i] = rand()*rand(); 
    }
    
    return array;
}

void printArray(int *array){
		for(int i =0;i<20;i++){
    	cout<<array[i]<<" "; 
     	}
     	cout<<"......"<<endl;	
} 


//选择排序
void Ssort(int *array,int size){
	for(int i = 0;i<size;i++){
		int min = i;
		for(int j=i;j<size;j++){
			if(array[min]>array[j])
			 min=j;
			
		}
		swap(array[i],array[min]);
	}
} 
 

//冒泡排序
void Bsort(int *array,int size){
	for(int i=0;i<size;i++)
		for(int j=1;j<size-i;j++)
			if(array[j-1]>array[j])	
			   swap(array[j-1],array[j]);					
}


//归并排序
void merge(int *array,int start,int end,int *result,int size) 
{
    int left_length = (end - start + 1) / 2 + 1;    
    int left_index = start;
    int right_index = start + left_length;
    int result_index = start;
    while(left_index<start + left_length && right_index <end + 1)  
    {
        if(array[left_index] <= array[right_index])
        	result[result_index++] = array[left_index++];
            
        else
        	result[result_index++] = array[right_index++];
    }
    while(left_index < start + left_length)
    	result[result_index++] = array[left_index++];
    	
    while(right_index <end+1)
    	result[result_index++] = array[right_index++];
}

void Msort(int *array,int start,int end,int *result,int size)
{
	
	switch(end - start){
		case 1:
			if(array[start] > array[end])
            swap(array[start],array[end]);      
        return;
		case 0:
			 return;
		default:
             Msort(array, start, (end - start + 1) / 2 + start, result,size);
             Msort(array, (end - start + 1) / 2 + start + 1, end, result,size);
            merge(array, start, end, result,size);
            for(int i=start;i<end+1;i++)
               array[i]=result[i];
	}

} 


// 快排
int Partition(int *array, int low, int high){
	int key=array[low]; 
	while(low<high){
		while(low<high && array[high]>=key){
			--high;
		} 
		array[low] = array[high];
		while(low<high && array[low]<=key){
			++low;
		}
		array[high] = array[low];
	}
	array[low] = key;
	return low;
}
void QSort(int *array,int low,int high){
	int pivotloc;
	if(low<high)
	{
		pivotloc = Partition(array,low,high);
		QSort(array,low,pivotloc-1);
		QSort(array,pivotloc+1,high);
	}
} 



//插入排序
void ISort(int *array,int size){
	int key; 
	for(int i=1;i<size;i++)
	{
	
		if(array[i]<array[i-1]){
			int j = i-1;
			key=array[i];
			while(j>=0 && array[j]>key){
				array[j+1]=array[j];	
				j--;
			}
			array[j+1]=key;
		}
	}
}

int main(){
     // 测试逻辑



     return 0}
	     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鼠不爱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值