选择排序
**第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。**以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
–《百度百科》
伪代码:(注意是伪代码,源码在最后!)
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)
冒泡排序
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
–《百度百科》
伪代码:
伪代码:(注意是伪代码,源码在最后!)
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
······
归并排序
- 将序列上每相邻的两个数字进行排序,
- 排序后的n/2 个有序序列每相邻的两个序列进行归并
- 重复步骤2,直到整个序列有序。
伪代码:(注意是伪代码,源码在最后!)
void merge_sort( *array,start,end, *result){
switch(end - start){
case 1: //只剩两个元素,直接比较排序
if(array[start]>array[end])
swap(array[start],array[end]);
return;
case 0://只剩一个元素,已有序,直接返回
return;
default
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;
}