代码改变世界

排序算法&复杂度

2017-08-10 16:52  SiestaKc  阅读(309)  评论(0编辑  收藏  举报

插入排序:直接插入排序

时间复杂度:O(n^2); 

空间复杂度:O(1);

稳定,简单

实现代码:

function insertSort(arr){
   for(var i=1;i<arr.length;i++){
   if(arr[i]<arr[i-1]){ //当a[i]>a[i-1]时,直接插入
    var j = i-1;   
    var x = arr[i];  //设立标兵参照数
    arr[i+1] = arr[i]; //向后移一个位置,一次归入一个数进行比较
    while(x<arr[j]){ //寻找插入位置
     arr[j+1] = arr[j];  //标兵比a[i-1]小时,再向前一位寻找插入位置
     j--;
    }
    arr[j+1] = x; //标兵比a[i-1]大时,则插入
   }
   }
}

 

冒泡排序

时间复杂度O(n^2) ;

空间复杂度O(1);

稳定、简单。

实现代码:

function bubbleSort(arr){
  if(arr == null || arr.length ==0){return ;} //检验数组是否为零
  for(var i=0;i<arr.length-1;i++){ 
    for(var j=arr.length;j>i;j--){ 
     if(arr[j]>arr[j+1]){ //相邻元素进行对比
       var tmp = arr[j]; //交换元素
       arr[j] = arr[j+1];
       arr[j+1] = tmp;
     }
    }
  }return arr; //返回数组
}
var arr = [21,1,4,2,5,7,4]; //定义数组
bubbleSort(arr); 

改进算法2:设置一个标志变量记录一趟排序中是否还存在数据交换,当一趟排序下来没有发生数据交换时,证明排序已经完成,则可以退出排序,而不用再做(n-i+1)趟多余的排序。

设置一个position标志标量,来记录每次排序最后一躺交换数据的位置,下一躺排序开始时,则扫描到position记录的位置结束。

实现代码:

function bubbleSort2(arr){
   var i=arr.length-1;
   while(i>0){
     var position = 0;//每躺开始,无记录交换
     for(var j=0;j<i;j++){
       if(arr[j]>arr[j+1]){
         position = j;   //标记:这一躺排序中数据交换到该位置
         var temp = arr[j];
         arr[j] = arr[j+1];
         arr[j+1] = temp;
        }
     i = position;//为下一躺排序做准备,数据扫描到该位置则结束(j<i)
   }
}

改进算法3:每次冒泡只能找到一个最大值或最小值,为增快排序的速度,每躺排序从正向和反向都进行一次冒泡,分别得到最大值和最小值。

function bubbleSort3(arr){
   var low = 0;
   var high = arr.length-1;
   var temp, j;
   while(low<high){ //正向冒泡找到最大值
    for(j=low;j<high;j++){
     if(arr[j]>arr[j+1]){
      temp = arr[j];
      arr[j]= arr[j+1];
      arr[j+1] = temp; //将arr[j]调换到arr[j+1]位置上来
     }
    -- high;//修改high的值,向前挪一个位置
   for(j=high;j>low;j--){ //反向冒泡,找到最小值
     if(arr[j]<arr[j-1]);
      temp = arr[j];
      arr[j] = arr[j-1];
      arr[j-1] = temp;//将arr[j-1]调换到arr[j]位置上来
    }
   ++low;//修改low的值,向后挪一个位置
    }
   }

选择排序

时间复杂度:O(n^2);

空间复杂度:O(1);

不稳定,简单。

实现代码:

function selectSort(arr){
   if(arr ==null || arr.length == 0){return ;}//判断数组不为0
   for(var i=0;i<arr.length-1;i++){
     var temp;
     var min =i; //当前选中的数与后面数组中的每一位相比
     for(var j=i;j<arr.length;j++){ //返回最小值的坐标
      if(arr[j]<arr[min]){//找到最小数值数的位置
       min = j;
      }
      }
     temp = arr[i]; //交换数据
     arr[i] = arr[min];
     arr[min] = temp;
   }
}

var arr =[1,45,37,5,48,15,37,26,29,2,46,4,17,50,52];
console.log(arr);

快速排序

时间复杂度:O(nlog2N);

空间复杂度:O(nlog2N);

不稳定,较复杂

实现代码:

选择第一个数为基数并且运用递归实现:

public class QuickSort{

    public static int partition(int arr[],int left, int right){

         int privotKey = arr[left]; //设置数组的第一个数为基准数
        while( left < right){
           while ( left < right && arr[right] >= privotKey) //从右向左开始查找小于基准数的数    
               right -- ;
               if(left<right) arr[left++] = arr[right]; //将小于基准数的移动到左边
           
           while(left < right  && arr[left] <= privotKey) //从左向右开始查找大于基数的数
               left++;
               if(left<right) arr[right--] = arr[left];
        
         }
         arr[left] = privoyKey;//当low=high时,便将基数赋值到中间位置
         return left; //返回基数所在的坐标值
     }

//递归函数,递归子系列

       public static void quickSort(int[]arr,int left, int right){
          
           if(left >= right) return ;
                 int privotPos = partition(arr,left,right); //取得基数位置
                 int quickSort(arr,left,privotPos-1);//左边子系列进行排序
                 int quickSort(arr,privotPos+1,right);//右边子系列排序
           
         }
    
         public static void sort(int[] arr){
             if(arr == null || arr.lengt ==0)
                  return ;
             quickSort(arr,0,arr.length-1);
        }
}

javascript实现代码:

function quickSort(arr){
   if(arr.length <= 1){return arr;} 
   var pivotIndex = Math.floor(arr.length / 2); //中间数位置值,向下一个数舍入,如 0.40=》0; 5.1=》6; -5.1=》-6
   var pivot = arr.splice(pivotIndex,1)[0]; //取中间数为基准数。splice(a,1);从a位置开始删除;
   var left = [];//定义一个左边空数组
   var right = []; //定义一个右边空数组
   for(var i=0;i<arr.length;i++){ //遍历数组
     if(arr[i]<pivot){ //比基准数小的添加进“左边数组”
       left.push(arr[i]);
     }else{//否则,添加进“右边数组”
       right.push(arr[i]);
     }
   } //使用递归,左边数组和右边数组进行重复的排序
   return quickSort(left).concat([pivot],quickSort(right));
};