常用排序算法

排序算法:http://www.cnblogs.com/eniac12/p/5329396.html#s3

1.直接插入排序

(1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

算法原理:

插入排序的基本方法是:每步将一个待排序序列按数据大小插到前面已经排序的序列中的适当位置,直到全部数据插入完毕为止。 
假设有一组无序序列 , , … , : 
(1) 将这个序列的第一个元素R0视为一个有序序列; 
(2) 依次把 , , … ,  插入到这个有序序列中; 

public insertSort(){ 
 int temp=0; 
 for(int i=1;i<a.length;i++){ 
 temp=a[i]; 
 for(j=i-1;j>=0&&temp<a[j];j--){ 
  a[j+1]=a[j]; //将大于temp的值整体后移一个单位 ,先不交换,一直后移
 } 
 a[j+1]=temp; 
 } 

 

2.简单选择排序

平均时间复杂度:O(n2)

(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;

然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。

public static void select_sort(int array[],int lenth){

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

       int min= i;
       for(int j=i+1;j<lenth;j++){
          if(array[j]<array[min]){
              min = j;//把最小的序号给min
          }
       }
       if(min != i){
           int temp = array[i];
           array[i] = array[min];
           array[min] = temp;
       }
   }
}

3、快速排序

https://baike.baidu.com/item/%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/369842?fr=aladdin&fromid=2084344&fromtitle=%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F

https://blog.csdn.net/vayne_xiao/article/details/53508973

1、平均时间复杂度:O(N*logN)

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key,即key=A[0];
3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]和A[i]互换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]和A[j]互换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。

 

C语言版本

void sort(int *a, int left, int right)
{
    if(left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/
    {
        return ;
    }
    int i = left;
    int j = right;
    int key = a[left];
     
    while(i < j)                               /*控制在当组内寻找一遍*/
    {
        while(i < j && key <= a[j])
        /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升
        序还是降序)2,没有符合条件1的,并且i与j的大小没有反转*/ 
        {
            j--;/*向前寻找*/
        }
         
        a[i] = a[j];
        /*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key是
        a[left],那么就是给key)*/
         
        while(i < j && key >= a[i])
        /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,
        因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/
        {
            i++;
        }
         
        a[j] = a[i];
    }
     
    a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/
    sort(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/
    sort(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/
                       /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/
}

一. 冒泡排序(BubbleSort)

  1. 平均时间复杂度:O(n2)

  2. java代码实现:

    public static void BubbleSort(int [] arr){
    
         int temp;//临时变量
         for(int i=0; i<arr.length-1; i++){   //表示趟数,一共arr.length-1次。
             for(int j=arr.length-1; j>i; j--){
    
                 if(arr[j] < arr[j-1]){
                     temp = arr[j];
                     arr[j] = arr[j-1];
                     arr[j-1] = temp;
                 }
             }
         }
     }

优化:

  • 针对问题:
    数据的顺序排好之后,冒泡算法仍然会继续进行下一轮的比较,直到arr.length-1次,后面的比较没有意义的。

  • 方案:
    设置标志位flag,如果发生了交换flag设置为true;如果没有交换就设置为false。
    这样当一轮比较结束后如果flag仍为false,即:这一轮没有发生交换,说明数据的顺序已经排好,没有必要继续进行下去。

    public static void BubbleSort1(int [] arr){
    
       int temp;//临时变量
       boolean flag;//是否交换的标志
       for(int i=0; i<arr.length-1; i++){   //表示趟数,一共arr.length-1次。
    
           flag = false;
           for(int j=arr.length-1; j>i; j--){
    
               if(arr[j] < arr[j-1]){
                   temp = arr[j];
                   arr[j] = arr[j-1];
                   arr[j-1] = temp;
                   flag = true;
               }
           }
           if(!flag) break;//就是说,如果n=10,此时i=5就已经排序完毕了,后面的5次就无需再继续了
       }
    }
posted @ 2018-03-30 11:42  Andrew_F  阅读(200)  评论(0编辑  收藏  举报