Lintcode 464. 整数排序 II 冒泡排序三种实现 直接插入排序 直接选择排序 java

一.冒泡排序

实现思路:https://blog.csdn.net/morewindows/article/details/6657829
Lintcode:https://www.lintcode.com/problem/sort-integers-ii/description

冒泡第一种

  1. 冒泡排序是非常容易理解和实现,,以从小到大排序举例:

设数组长度为N。

1.比较相邻的前后二个数据,如果前面数据大于后面的数据,就将二个数据交换。

2.这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。

3.N=N-1,如果N不为0就重复前面二步,否则排序完成。
按照此代码 编写,在LintCode 运行超时,这道题目是nlgN的时间复杂度,冒泡不行,A了80多
这里写图片描述

public class Solution {
    /**
     * @param A: an integer array
     * @return: nothing
     */
    public void sortIntegers2(int[] A) {
        // write your code here
        BuddleSort(A);
    }
    public void BuddleSort(int [] A)
    {
        for(int i=A.length-1;i>0;i--)
        {
            for(int j=0;j<i;j++)
            {
                if(A[j] > A[j+1])
                {
                    int temp = A[j];
                    A[j] = A[j+1];
                    A[j+1] = temp;
                }
            }
        }
    }
}

冒泡第二种优化方法

下面对其进行优化,设置一个标志,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成
运行结果与第一种一样,超时,看来优化还是不给力

public class Solution {
    /**
     * @param A: an integer array
     * @return: nothing
     */
    public void sortIntegers2(int[] A) {
        // write your code here
        BuddleSort(A);
    }
    public void BuddleSort(int [] A)
    {
        boolean flag = false;
        for(int i=A.length-1;i>0;i--)
        {
            flag = false;
            for(int j=0;j<i;j++)
            {

                if(A[j] > A[j+1])
                {
                    int temp = A[j];
                    A[j] = A[j+1];
                    A[j+1] = temp;
                    flag = true;
                }
            }
            if(flag == false)
                return;
        }
    }
}

冒泡的第三种优化

再做进一步的优化。如果有100个数的数组,仅前面10个无序,后面90个都已排好序且都大于前面10个数字,那么在第一趟遍历后,最后发生交换的位置必定小于10,且这个位置之后的数据必定已经有序了,记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。
依旧只A了83%,果然冒泡的时间复杂度是无法A这道题的
说一下我的代码思路:只有在冒泡的过程中发生了交换也就是flagSwap = true,那么才说明在索引j与j+1这两个数发生了交换,才标记j+1这个索引(flag =j+1),如果没发生交换的话,依旧令i=flag会发生循环无法跳出的情况,因为没有交换,flag的值没有变化,如果令i=flag那么会一直重复没有交换,i=flag这个过程,i就一直无法为0结束这个循环,会发生运行时超时的错误,附上我的错误代码,供大家理解我刚才说的话的意思。
这里写图片描述
代码:

public class Solution {
    /**
     * @param A: an integer array
     * @return: nothing
     */
    public void sortIntegers2(int[] A) {
        // write your code here
        BuddleSort(A);
    }
    public static void BuddleSort(int [] A)
    {
        int flag = -1;
        boolean flagSwap = false;
        for(int i=A.length-1;i>0;i--)
        {
            flagSwap = false;
            for(int j=0;j<i;j++)
            {

                if(A[j] > A[j+1])
                {
                    int temp = A[j];
                    A[j] = A[j+1];
                    A[j+1] = temp;
                    flag = j+1;
                    flagSwap = true;
                }
            }
            if(flagSwap)
                i = flag;
        }
    }
}

错误代码

    public static void BuddleSort(int [] A)
    {
        int flag = -1;
        for(int i=A.length-1;i>0;i--)
        {
            for(int j=0;j<i;j++)
            {

                if(A[j] > A[j+1])
                {
                    int temp = A[j];
                    A[j] = A[j+1];
                    A[j+1] = temp;
                    flag = j+1;
                }
            }
            System.out.println(i + " " + flag+ Arrays.toString(A));
            i = flag;
        }
    }

用例,[1, 1, 2, 3, 4, 7, 8, 9],这样会会一直卡死在i=1,flag=2,然后i=flag i = 2然后在for循环中i减一变成1,然后没交换flag还是2,i=flag这样重复这个过程。

直接插入排序

参考链接:https://blog.csdn.net/morewindows/article/details/6665714
最终AC了94%,时间复杂度还是高啊
这里写图片描述
附上代码:

public class Solution {
    public void sortIntegers2(int[] A) {
        InsertSort(A);
    }
    public void InsertSort(int[] A)
    {
        int i,j,k;
        for(i=1;i<A.length;i++)
        {
            for(j=i-1;j>=0;j--)
            {
                if(A[j] <= A[i])//寻找第一个小于A[i]的位置,也就是[i]该插入的地方
                    break;
            }
            if(j != i-1) //这个判断的意思是如果是刚好A[i-1]这个地方小于A[i],那么不需要操作
            {
                int temp = A[i];
                for(k=i-1;k>j;k--)
                    A[k+1] = A[k];
                A[k+1] = temp;//循环结束k=j,故需要k+1放在该放的位置上
            }
        }
    }
}

直接选择排序

参考链接:https://blog.csdn.net/morewindows/article/details/6671824
时间复杂度不够,只A了89%
代码:

public class Solution {
    public void sortIntegers2(int[] A) {
        SelectSort(A);
    }
    public void SelectSort(int[] A)
    {
        for(int i=0;i<A.length;i++)
        {
            int minIndex = i;
            for(int j=i;j<A.length;j++)
            {
                if(A[j] < A[minIndex])
                    minIndex = j;
            }
            int temp = A[i];
            A[i] = A[minIndex];
            A[minIndex] = temp;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/WantFlyDaCheng/article/details/81565260