选择排序与插入排序

排序算法O(n*2)

这种比较基础,很多时候我们在面临一个问题要从最简单的方法解决,从而优化

编码简单,易于实现,是一些简单场景的首选,汇编语言也可以用

特殊情况下,简单排序更加有效

能延伸更复杂的排序,如希尔排序

作为子过程,用于改进更加负载的排序算法

 

选择排序

8,6,2,3,1,5,7,4

首先在整个数组找到第一名 1,将1和8交换,1就是最终位置,之后找最小的以此类推

具体实现如下

template<typename T>

void selectionSort( T arr[] , int n){

         for(inti=0 ; i<n ; i++){

                   //寻找[i,n)最小值

                   intminIndex = i;

                   for(int j = i+1 ; j < n ; j++)

                            if(arr[j] < arr[minIndex])

                            minIndex= j;

                   swap(arr[i] , arr[minIndex]);

}

}

以下是php版本

<?php
function selectionSort(array $arr){
    $n = count($arr);
    for($i=0;$i<$n;$i++){
        $minIndex = $i;
        for($j = $i+1 ; $j < $n ; $j++){
            if($arr[$j] < $arr[$minIndex])
                $minIndex=$j;
        }
        $temp = $arr[$i];
        $arr[$i] = $arr[$minIndex];
        $arr[$minIndex] = $temp;
    }
    return $arr;
}

$a = [5,6,1,23,56,7];
$a = selectionSort($a);
var_dump($a);

 

插入排序:Insertion Sort整理扑克牌

把每张牌插入合适位置,当最后一张操作完成就结束了

首先对第一个元素不动,看第二个,把第二个放入前面合适的位置

template<typename T>

void insertionSort(T arr[], int n ){

         for(int i = 1 ; i<n ;i++){

         //第0个元素已经有序了

                   //寻找元素arr[i]合适的插入位置

                   for(intj = i; j>0&&arr[j] < arr[j-1];j--){

                            swap(arr[j],arr[j-1]);

}

         }

}

插入排序和选择排序的区别:插入排序第二次循环可以提前结束,理论上所以插入更快一些,但是实际却不是这样。

插入排序的在遍历的通时也在不停地交换,遍历比比较操作耗时,因为每一次交换,都要3次赋值。对数组还要访问索引所在元素。

先把i复制一个副本,看看i是不是该待在i,i比i-1如果小,i不该在这个位置,所以把i-1放到i….

改进后的插入排序

template<typename T>

void insertionSort(T arr[], int n ){

         for(int i = 1 ; i<n ;i++){

         //第0个元素已经有序了

                   //寻找元素arr[i]合适的插入位置

                   Te = arr[i];

                   intj;//j保存元素e应该插入的位置

                   for(intj = i; j>0&&arr[j-1] > e;j--){

                            arr[j] = arr[j-1];

}

arr[j] = e;

         }

}

不但不用交换,还提前终止所以就比较快了。加入本身基本上就有序,可以很快找到位置,此时插入排序效率比较高,有序性高的话就比较快。我们很多时候都是有这种近乎有序的。

如果完全有序就是o(n)。插入排序在很多排序中作为子排序优化。

以下是php版本

<?php
function insertionSort(array $arr){
    $n = count($arr);
    for($i =1;$i<$n;$i++){
        $e = $arr[$i];
        for($j=$i;$j>0&&$arr[$j-1]>$e;$j--){
            $arr[$j] = $arr[$j-1];
        }
        $arr[$j] = $e;
    }
    return $arr;
}

$a = [5,6,1,23,56,7];
$a = insertionSort($a);
var_dump($a);

 

 

辅助:

生成1000个数

在文件SortTestHelper.h中声明一系列辅助函数

把他们放在一个命名空间中

#include <iosstream>

#include <ctime>

#inclde <cassert>

using namespace std;

namespace SortTestHelper{

         //生成有n个元素,随机范围[rangeL,rangeR]

         int*generateRandomArray(int n, int rangeL,int rangeR){

                   assert(rangeL <= rangeR);

                   int*arr = new int[n];

                   srand(time(NULL));

                   for(int I = 0 ; i < n ; i++_)

                            arr[i]= rand() % ( rangeR – rangeL +1 ) + rangeL;

                   returnarr;

}

 

生成近乎随机

int *generateNearlyOrderedArray(intn , int swaptimes){

         int *arr = new int[n];

         for(int i=0;i<n;i++)

                   arr[i]=i;

         sand(time(Null));

         for(int i=0 ;i< swapTimes;i++){

                   int posx =rand()%n;

                   int posy =rand()%n;

swap(arr[posx], arr[posy]);

}

}

 

template<typenameT>

voidprintArray(T arr[],int n){

         for (int i=0;i<n;i++)

                   cout<<arr[i]<< ” ”;

         cout << endl;

        

         return;

}

//测试排序算法

template<typenameT>

void testSort(string sortName, void(*sort)(T[],int),T arr[], int n){

         clock_t startTime = clock();

sort(arr,n);

clock_t endTime = clock();

assert( isSorted(arr,n) );//不放在endTime前因为性能不能包含,会干扰,而且如果sort错误那么打印输出会中断

cout << sortName <<” : ” <<double(endTime -startTime) / CLOCKS_PER_SEC<<” s”<<endl;

return;

// CLOCKS_PER_SEC标准库定义的宏,每秒钟运行的时钟周期个数

}

int*copyIntArray(int a[],int n){

         int* arr  = new int[n]

         copy(a,a+n,arr);

         return arr;

}

 

template<typenameT>

bool isSorted(Tarr[], int n){

         for(int i=0;i<n-1;i++)

                   if(arr[i]>arr[i+1])

                            return false;

         return true;

}

}

 

 

测试用例:

#inclue “SortTestHelper.h”

int main(){

         intn =10000;

         int*arr = SortTestHelper:: generateRandomArray         selectionSort(n,0,n);

//      selectionSort(arr , n );

//      SortTestHelper::printArray(arr,n);

         SortTestHelper::testSort(“SelectionSort”, selectionSort, arr,n);

         delete[]arr; //内存释放,防止内存泄露

         return0;

}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值