冒泡、选择、插入和希尔排序
public class BubbleSort { /* 基本思想: 通过对待排序序列从前往后(从下标较小的元素开始),依次比较相邻两元素的值,若发现逆序则交换, 使值较大的元素逐渐从前面移向后部。 以从小到大为例:每一趟都确定一个当前最大数的位置,共走n-1趟。 */ public static void bubbleSort(int[] arr){ //临时变量,用来交换数组不同位置的两个数 int temp = 0; //优化效率的一个标志 boolean flag= false; for(int i=0;i<arr.length-1;i++){ for (int j = 0; j <arr.length-1-i; j++) { //“-i"每一轮冒泡以后最大数已经就位,没有必要重复比较 if(arr[j]>arr[j+1]){ temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; //在该轮中如果进行过交换则将flag更改为true // (如果flag一次都没有进行过交换则为false,证明此时数组已经是一个有序数组,可以直接退出程序) flag=true; } } if(!flag){ break; }else { flag=false; } } } }
/* 基本思想: 第一次从arr[0]-—arr[n-1]中找到最小的数与arr[0]交换;第二次从arr[1]--arr[n-1] 中找到最小的数与arr[1]交换,以此类推,直到完成排序。 说明: 1.选择排序一共有数组大小-1次排序; 2.每一轮排序都是一个循环 2.1先假定当前这个数最小; 2.2然后和后面的每个数进行比较,如发现比前面更小的数就重新确定最小数并确定下标; 2.3当打到最后时,就找到了本轮的最小数; 2.4进行交换。 */ //时间复杂度O(n2) public static void selectSort(int[] arr){ for(int i=0;i<arr.length-1;i++){ int minIndex = i; int min = arr[i]; //(i+1)从上一轮的下一个开始选择 for(int j=i+1;j<arr.length;j++){ if(min>arr[j]){ //找到本轮的最小数和他的下标 min=arr[j]; minIndex=j; } } //交换 if(minIndex!=i){ arr[minIndex] = arr[i]; arr[i]=min; } } } }
public class InsertSort { /* 简单插入排序是对于欲排序的元素已插入的方式找到该元素的位置,以达到排序的目的 基本思想: 把n个待排序的元素看成一个有序表和无序表 开始时有序表中只有一个元素,无序表中有n-1个元素,排序过程中每一次从无序表 中取出第一个元素,把他的排序码与有序表中的排序码依次进行比较,将它插入到有序表 中的适当位置,使之成为新的有序表。 */ public static void insertSort(int[] arr){ for(int i=1;i<arr.length;i++){ int value = arr[i];//待插入的数 int Index = i-1;//待插入数的前一个数的坐标(待插入数与有序表中第一个数比较的下标) //保证不越界 待插入数的位置还没有找到 while(Index>=0&&value<arr[Index]){ //将比待插入数大的移到正确的位置 arr[Index+1] = arr[Index]; //继续与下一个比较 Index--; } //位置找到,并完成插入 arr[Index+1]=value; } } }
/* 也是一种插入排序 简单插入排序的问题:如果较小的数排在后面,那么厚仪的次数明显增加,会影响效率 希尔排序的基本思想: 把数组按下标的一定增量分组,对每一组使用直接插入排序算法排序;随着增量 逐渐减少,每组包含的关键词与来越多,当增量减少到1时,完成最后一次简单插入排序 算法结束。 */ //交换法 public static void shellSort(int[] arr) { int temp = 0; for(int gap = arr.length / 2; gap > 0; gap /= 2) { for(int i = gap; i < arr.length; ++i) { for(int j = i - gap; j >= 0; j -= gap) { if (arr[j] > arr[j + gap]) { temp = arr[j]; arr[j] = arr[j + gap]; arr[j + gap] = temp; } } } } } //位移法{(效率较高) public static void shellSort2(int[] arr) { //所谓的增量就是分为几组,在这里就是gap在逐步减小 for(int gap = arr.length / 2; gap > 0; gap /= 2) { //遍历各组中的所有元素,一改组下标最大的元素为起点 for(int i = gap; i < arr.length; i++) { int j = i; int temp = arr[i]; if (arr[i] < arr[i - gap]) { while(j - gap >= 0 && temp < arr[j - gap]) { arr[j] = arr[j - gap]; j -= gap; } arr[j] = temp; } } } } }