1. 程式人生 > >排序演算法(一)氣泡排序,簡單選擇排序,直接插入排序,希爾排序

排序演算法(一)氣泡排序,簡單選擇排序,直接插入排序,希爾排序

氣泡排序,簡單選擇排序,直接插入排序是三種複雜度為O(n2)的演算法,希爾排序在特殊增量序列的時候可以獲得複雜度為O(n3/2)

氣泡排序

1、最簡單的排序實現

這裡把每個數和這個數之後的每個數比較,大於就交換位置。
缺點:多出了很多次沒有用的交換

public class mysort {
    public void sort(int[] array)
    {
        if(array.length<=1) return;
        for(int i=0;i<array.length-1;i++)
        {
            for
(int j=i+1;j<array.length;j++) { if(array[i]>array[j]) { int temp = array[i]; array[i] = array[j]; array[j] = temp; } } } } }

2、氣泡排序

從後向前交換相鄰的,這樣在交換的過程中附帶會把略小的交換到前面去
即每次把最小的數交換到前面去,像冒泡一樣

public class mysort {
    public void sort(int[] array)
    {
        for(int i=0;i<array.length;i++)
        {
            for(int j=array.length-1;j>i;j--)
            {
                if(array[j]<array[j-1])
                {
                    int temp = array[j];
                    array
[j] = array[j-1]; array[j-1] = temp; } } } } }

3、氣泡排序改進演算法

設定一個flag用於後面的數是否已經排序,如果已經排好(沒有交換)則後面的迴圈不需要再繼續

public class mysort {
    public void sort(int[] array)
    {
        boolean hasSorted = false;
        for(int i=0;(i<array.length) && (!hasSorted);i++)
        {
            hasSorted = true;
            for(int j=array.length-1;j>i;j--)
            {
                if(array[j]<array[j-1])
                {
                    int temp = array[j];
                    array[j] = array[j-1];
                    array[j-1] = temp;
                    hasSorted = false;
                }
            }
        }
    }

}

簡單選擇排序

和冒泡相比卻只交換當前數和後面數中最小的數,減少了交換的次數

public class mysort {
    public void sort(int[] array)
    {
        if(array.length<2) return;
        for(int i=0;i<array.length-1;i++)
        {
            int min = i;
            for(int j=i+1;j<array.length;j++)
            {
                if(array[j]<array[min])
                    min = j;
            }
            if(min!=i)
            {
            int temp = array[min];
            array[min] = array[i];
            array[i] = temp;
            }
        }
    }

}

直接插入排序

基本思想:將新的數不斷插入已經排序好的序列中

public class mysort {
    public void sort(int[] array)
    {
        if(array.length<2) return;
        for(int i=1;i<array.length;i++)
        {
            //[0,i-1]是已經從小到大排好序的陣列,如果新的數比原本最大的數小,則需插入原陣列
            if(array[i]<array[i-1])
            {
                //num為需要插入的新值
                int num = array[i];
                //如果當前陣列中的某個數比需要插入的num大,則後移一位
                int j;
                for(j=i-1;(j>=0)&&(array[j]>num);j--)
                {
                        array[j+1] = array[j];
                }
                //插入num
                array[j+1] = num;
            }
        }
    }

}

希爾排序

遍歷陣列,相隔某個增量比較兩個數,前者大於後者則交換,增量不斷變小。增量變小的規律目前還是個難題,因為是跳躍式的,演算法也不夠穩定

public void xier(int[] arr)
    {
        if(arr==null || arr.length==0) return;
        int increment = arr.length;
        int j = 0;
        do{
            increment = increment/3+1;
            for(int i=increment;i<arr.length;i++)
            {
            //將i-incre,i-2incre,...所有的i-n*incre的比arr[i]大的數都像後挪動incre
                int temp = arr[i];
                for(j=i-increment;j>=0 && arr[j]>temp;j-=increment)
                {
                    arr[j+increment] = arr[j];
                }
                arr[j+increment] = temp;
            }

        }
        //必須保證最後一個incrment=1
        while(increment>1);
    }