读书笔记——简单排序算法

来源:互联网 发布:网络带来的危害 编辑:程序博客网 时间:2024/06/17 14:47

简单选择排序

简单选择排序的原理是,遍历一个序列,找到最小值的元素,将其与序列第一个元素交换位置,之后将第二个元素至最后一个元素作为下一个待排序序列遍历,经过n-1次遍历后初始序列即被排序。

    public int[] SelectSort(int[] arr){        int temp;        int small;//代表本次遍历中最小的元素的下标。        //一共执行n-1次,n为数组大小        for(int i=0;i<arr.length-1;i++){            small=i;            //从本序列的第二个元素开始遍历            for(int j=i+1;j<arr.length;j++){                //若此元素更小,更新small                if(arr[j]<arr[small]) small = j;            }            //交换序列首位的元素和本次遍历中寻找到的最小的元素            temp = arr[i];            arr[i] = arr[small];            arr[small] = temp;        }        return arr;    }
简单选择排序的时间复杂度与元素的初始排列无关,总为O(n²)。简单选择排序算法不是稳定的排序算法。例如下列排序过程:
遍历次数 数组变化情况 初始状态 2 3 2 1 1 1 3 2 2 2 1 2 3 2 3 1 2 2 3
可以发现粗体的2排序后到了非粗体的2的后面,说明简单选择排序算法是不稳定的。

直接插入排序

直接插入排序的原理是,以第一个元素为初始序列,然后遍历剩余的元素,按照大小插入初始序列,最后形成一个有序序列。直接插入排序需要经过n-1次插入。

    public int[] InsertSort(int[] arr){        int temp;        int j;        //遍历n-1遍        for (int i = 1; i < arr.length; i++) {            j=i;            temp = arr[i];//存储要插入的元素            //从后往前寻找插入位置            while(j>0 && temp<arr[j-1]){                //如果待插入元素比此元素小,则将此元素往后移一格                arr[j] = arr[j-1];                //j指针前移一格,准备与前一个元素比较                j--;                                    }            arr[j]=temp;//插入元素        }        return arr;    }

最好情况下,初始序列是有序的,直接插入排序只需要遍历n-1次,每次插入只需要比较一次就直接插入,此时时间复杂度为O(n)。
最坏情况下,初始序列是倒序的,直接插入排序需要遍历n-1次,并且每次对比都需要执行i次,此时时间复杂度为O(n²)。但是如果将while循环的条件”temp<arr[j-1]“改为”temp<=arr[j-1]“,则此算法就变为不稳定的排序算法。

冒泡排序

冒泡排序的原理是,以数组为初始序列,遍历进行相邻元素的比较,若后者较小则交换位置,一次遍历之后当前序列的最大的元素就成为了最后一个元素,以第一个元素到第n-1个元素为下一个序列进行遍历,直到某次遍历中不发生交换元素的事件,则数组有序。冒泡排序算法最多遍历n-1次。以下为优化版的冒泡排序。

    public int[] BubbleSort(int[] arr){        int temp;        int i,j,last;        i=arr.length-1;        //如果某次执行中i=0,则说明数组已有序。        while(i>0){            last=0;//初始化last            for (j = 0; j < i; j++) {                if(arr[j+1]<arr[j]){                    //若后者比前者小,则交换元素                    temp = arr[j];                    arr[j]=arr[j+1];                    arr[j+1]=temp;                    //记录最后一次交换元素的位置                    last=j;                }            }            i=last;//以最后一次交换元素的位置为界线再次遍历。        }        return arr;    }

上述示例代码中使用了last变量,使得执行遍历的次数得以变少。冒泡排序的时间复杂度与直接插入排序类似,最好的情况下,数组已有序,只需要遍历一次,时间复杂度为O(n);最坏的情况下,数组为倒序,则需要遍历n-1次,时间复杂度为O(n²)。冒泡排序是稳定的排序算法。