几种常见的排序算法

来源:互联网 发布:阳光网络伴我成长 编辑:程序博客网 时间:2024/04/24 14:01

冒泡排序

思路:从第0个到第n个,和相邻的元素进行相比,如果比相邻的大的话,那么就交换二者顺序,这样的话0到n范围内的最大的数就放到n的位置。接着下一次操作,第0个到第n-1个,将0到n-1范围内的最大值放到n-1。重复执行,最后数组从小到大排列。

public static void bubble(int array[])    {        for (int i = array.length-1; i >0;i--) {            for(int j=0;j<i;j++)            {                if(array[j]>array[j+1])                {                    swap(array,j+1,j);                }            }        }    }

排序过程:
3 6 8 15 1 20
3 6 8 1 15 20
3 6 1 8 15 20
3 1 6 8 15 20
1 3 6 8 15 20

选择排序

思路:遍历第i到第n个,找到i到n范围内最小的数,然后放在i的位置。接着遍历i+1到第n个,找到i+1到n范围内最小的数,然后放在i+1的位置,重复执行下去,最后数组从小到大排列。

public static void selectSort(int array[])    {        for (int i = 0; i < array.length; i++) {            int min=array[i];            int index=i;            for (int j = i; j < array.length; j++) {                if(array[j]<min)                {                    min=array[j];                    index=j;                }            }            swap(array,index,i);        }    }

排序过程:
1 3 20 8 15 6
1 3 20 8 15 6
1 3 6 8 15 20
1 3 6 8 15 20
1 3 6 8 15 20
1 3 6 8 15 20

插入排序

思路:如第0到5范围内的数从小到大排列,第六个数记为temp,此时第temp比第5个数小,那么第5个数往后退,接着再与第4个数比较,如果还是比第4个数小,那么第4个数继续后退,接着如果不小于第3个数,这个时候将temp存到4的位置 。总的来说,就是在一个有序范围内,插入一个该范围之外的数,随着执行下,有序范围逐渐扩大,最后整体有序。

public static void insert(int array[])    {        for (int i = 1; i < array.length; i++) {            int temp=array[i];            int j=i;            while(j>0&&temp<array[j-1])            {                array[j]=array[j-1];                j--;            }            array[j]=temp;                    }    }

排序过程:
3 6 20 8 15 1
3 6 20 8 15 1
3 6 8 20 15 1
3 6 8 15 20 1
1 3 6 8 15 20

希尔排序

思路:希尔排序是在插入排序的基础上进一步改进的。
插入排序有可以改进的地方

  • 插入排序每一次移动只能移动一位,而希尔排序可以按步长移动。
  • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
    所以针对这两点,希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
    总的来说,希尔排序的最后一步是插入排序,但是在插入排序之前,实现了基本有序。
public static void shell(int array[])    {        int gap=array.length/2;        //控制步长        while(gap!=0)        {                        for (int i = 0; i < gap; i++) {                //插入排序                for (int j = i+gap; j < array.length; j=j+gap) {                    int temp=array[j];                    int p=j;                    while(p>=gap&&temp<array[p-gap])                    {                        array[p]=array[p-gap];                        p=p-gap;                    }                    array[p]=temp;                }            }            gap=gap/2;        }    }

快速排序

最核心的思想是实现在一个范围内,以n为基准点,左边的数不大于基准点,右边的数不小于基准点。接下来左边的作为一个整体,同样实现上面的要求,右边的作为一个整体也实现上面的要求(左边的数不大于基准点,右边的数不小于基准点)。自顶向下执行下去,最后局部有序实现整体有序。

public static void quickSort(int array[],int start,int end)    {        if(start<end)        {            int n=findPoint(array,start,end);            quickSort(array,start,n-1);            quickSort(array,n+1,end);        }    }    public static int findPoint(int array[],int start,int end)    {        int temp=array[start];        while(start<end)        {            while(start<end&&array[end]>=temp)            {                end--;            }            if(start<end)            {                array[start]=array[end];            }            while(start<end&&array[start]<=temp)            {                start++;            }            if(start<end)            {                array[end]=array[start];            }        }        array[start]=temp;        return start;    }

排序过程:
1 3 2 6 8 12 7 15 20
1 3 2 6 8 12 7 15 20
1 2 3 6 8 12 7 15 20
1 2 3 6 7 8 12 15 20
1 2 3 6 7 8 12 15 20
1 2 3 6 7 8 12 15 20

原创粉丝点击