一、冒泡排序:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //两两比较,大的往后边放,经过一轮比较,最大的元素就会出现在最后面。 5 public class BubbleSort { 6 public static void main(String[] args) { 7 int [] arr={24,69,80,57,13}; 8 //i代表比较轮次 9 for (int i = 0; i < arr.length - 1; i++) { 10 for (int j = 0; j < arr.length - 1-i; j++) { 11 //arr[j]代表要比较的元素,arr[j+1]代表它后边的元素 12 if(arr[j]>arr[j+1]){ 13 int t=arr[j]; 14 arr[j]=arr[j+1]; 15 arr[j+1]=t; 16 } 17 } 18 } 19 System.out.println(Arrays.toString(arr)); 20 } 21 }
二、选择排序:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //每一次拿一个元素,跟后面的元素挨个比较,小的往前换,经过一轮后,最小的就会换在最前面 5 public class SelectSort { 6 public static void main(String[] args) { 7 int [] arr={24,69,80,57,13}; 8 for (int index = 0; index < arr.length - 1; index++) {//index代表比较轮次和要比较元素的索引 9 for (int j = 1+index; j < arr.length; j++) { 10 //j=1+index 下一个元素的索引,不用和自己比。 11 //arr[index]代表要比较的元素,arr[j]表示下一个元素 12 if(arr[index]>arr[j]) { 13 int t = arr[index]; 14 arr[index] = arr[j]; 15 arr[j] = t; 16 } 17 } 18 } 19 System.out.println(Arrays.toString(arr)); 20 } 21 }
三、直接插入:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //将后面的元素,插入之前的有序列表,使其仍然保持有序。 5 public class StraightInsertionSort { 6 public static void main(String[] args) { 7 int []arr={1,2,0,3,4,6,10,-1}; 8 Sort1(arr); 9 System.out.println(Arrays.toString(arr)); 10 sort2(arr); 11 System.out.println(Arrays.toString(arr)); 12 } 13 14 private static void sort2(int[] arr) { 15 //外层控制循环次数 16 for (int i = 0; i < arr.length; i++) { 17 //里边比前一项小就换,直到有序为止。 18 for (int j = i; j >0; j--) { 19 if(arr[j]<arr[j-1]){ 20 int t=arr[j]; 21 arr[j]=arr[j-1]; 22 arr[j-1]=t; 23 } 24 } 25 } 26 } 27 28 private static void Sort1(int[] arr) { 29 for (int i = 1; i < arr.length;i++) { 30 int j=i; 31 while (j>0&&arr[j]<arr[j-1]){ 32 int t=arr[j]; 33 arr[j]=arr[j-1]; 34 arr[j-1]=t; 35 j--; 36 } 37 } 38 } 39 }
四、希尔排序:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //选择一个合适的增量,经过一轮插入排序后,让数组大致有序,然后缩小增量进行插入排序,直到增量为1结束排序。 5 public class ShellSort { 6 public static void main(String[] args) { 7 int[] arr={46,55,13,42,17,94,5,70}; 8 //kunth克努特序列选增量 9 int zengliang =1; 10 while (zengliang<arr.length/3){ 11 zengliang=3*zengliang+1; 12 } 13 //增量为一半h=arr.lenth/2; 14 for (int h = zengliang; h >0; h=(h-1)/3) { 15 for (int i =h; i < arr.length;i++) { 16 //j>增量-1;j=j-zengliang; 17 for (int j = i; j >h-1; j-=h) { 18 if(arr[j]<arr[j-h]) { 19 int t = arr[j]; 20 arr[j] = arr[j-h]; 21 arr[j-h] = t; 22 } 23 } 24 } 25 } 26 System.out.println(Arrays.toString(arr)); 27 } 28 }
五、快速排序:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //比大小再分区。从数组中取出一个数,作为基准数,将大的数放右边,小的放左边。 5 //再对左右分区重复第二步,直到各分区只有一个数为止。 6 //挖坑填数。 7 //1.挖出一个基准数,形成第一个坑。 8 //2.从后往前挖比它小的数填到上一个坑中(挖基准数的坑) 9 //3.从前往后挖一个大于或等于它的数填到上一个坑中 10 //4.重复2.3步。 11 public class QuickSort { 12 public static void main(String[] args) { 13 int[]arr={2,3,5,8,4,1,7,6,9,10}; 14 chaifen(arr,0,arr.length-1); 15 System.out.println(Arrays.toString(arr)); 16 } 17 18 private static void chaifen(int[] arr, int start, int end) { 19 if(start<end){ 20 int index=getIndex(arr,start,end); 21 //左右拆分 22 chaifen(arr,start,index-1); 23 chaifen(arr,index+1,end); 24 } 25 } 26 27 /** 28 * @param arr 传进来的数组 29 * @param start 开始索引 30 * @param end 结束索引 31 * @return 返回基准数的索引 32 */ 33 private static int getIndex(int[] arr, int start, int end) { 34 //定义起始结束索引 35 int i=start; 36 int j=end; 37 //定义基准数 38 int x=arr[i]; 39 //循环 40 while (i<j){ 41 //从后往前找比基准数小的数 42 while(i<j&&arr[j]>=x){ 43 j--; 44 } 45 //填数到上一个坑中 46 if(i<j){ 47 arr[i]=arr[j]; 48 i++; 49 } 50 //从前往后找大于等于基准数的数 51 while(i<j&&arr[i]<x){ 52 i++; 53 } 54 //填数到上一个坑中 55 if(i<j){ 56 arr[j]=arr[i]; 57 j--; 58 } 59 } 60 //循环结束,把基准数填进最后一个坑(i=j)中,也就以基准数为界限分成左右两部分 61 arr[i]=x;//填进去 62 return i;//返回基准数所在位置的索引 63 } 64 }
六、归并排序:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 //分而治之。假设初始序列有N个记录,则可以看成N个有序的子序列,每个子序列的长度为1,然后两两合并得到一个N/2 5 //个长度为2或1的有序子序列,再两两归并...如此重复直到得到一个长度为N的有序序列为止。 6 public class MergeSort { 7 public static void main(String[] args) { 8 int[]arr={2,3,5,8,4,1,7,6,9,10}; 9 chaifen(arr,0,arr.length-1); 10 System.out.println(Arrays.toString(arr)); 11 } 12 13 private static void chaifen(int[] arr, int startIndex, int endIndex) { 14 int centerIndex=(startIndex+endIndex)/2; 15 if(startIndex<endIndex){ 16 //左边递归拆 17 chaifen(arr,startIndex,centerIndex); 18 //右边递归拆 19 chaifen(arr,centerIndex+1,endIndex); 20 //合并 21 hebing(arr,startIndex,centerIndex,endIndex); 22 } 23 } 24 25 private static void hebing(int[] arr, int startIndex, int centerIndex, int endIndex) { 26 //定义一个临时数组 27 int[] tempArray=new int [endIndex-startIndex+1]; 28 //定义临时数组起始索引 29 int index=0; 30 //定义第一个数组起始索引 31 int i=startIndex; 32 //定义第二个数组起始索引 33 int j=centerIndex+1; 34 //遍历数组开始归并 35 while(i<=centerIndex&&j<=endIndex){ 36 if(arr[i]<=arr[j]){ 37 tempArray[index]=arr[i]; 38 i++;//增加索引 39 }else{ 40 tempArray[index]=arr[j]; 41 j++;//增加索引 42 } 43 index++;//临时数组增加索引 44 } 45 //处理左边剩余元素 46 while (i<=centerIndex){ 47 tempArray[index]=arr[i]; 48 i++; 49 index++; 50 } 51 //处理右边剩余元素 52 while (j<=endIndex){ 53 tempArray[index]=arr[j]; 54 j++; 55 index++; 56 } 57 //遍历临时数组赋值到原始数组 58 for (int m = 0; m < tempArray.length; m++) { 59 arr[m+startIndex]=tempArray[m]; 60 } 61 } 62 }
七、基数排序LSD:
1 package com.duan.array; 2 3 import java.util.Arrays; 4 5 //分配再收集。按个位-十位-百位-... 位数从低位开始排序。LSD法。 6 public class RadixSort { 7 public static void main(String[] args) { 8 int []arr={0,2,11,30,49,50,100,123,187,543 }; 9 Sort(arr); 10 System.out.println(Arrays.toString(arr)); 11 } 12 13 private static void Sort(int[] arr) { 14 //定义一个二维数组 15 int[][]tempArr=new int [10][arr.length];//里面一维数组的长度和待排数组的长度一样 16 //定义一个统计的一维数组,用来统计二维数组中放的数字个数 17 int[]count=new int [10];//长度和二维数组保持一致 18 //获取数组中的最大数 19 int max=getMax(arr); 20 //计算数组中最大的数有几位,这也是我们需要比较的轮次 21 int lunci = String.valueOf(max).length(); 22 for (int i = 0, n = 1; i < lunci; i++, n *= 10) { 23 for (int j = 0; j < arr.length; j++) { 24 //获取每个位上的数字 25 int shu = arr[j] / n % 10; 26 //我们找一个二维数组,数组中放10个桶,这个桶就是一维数组 27 // count[shu]++ 意思是,二维数组的桶中放一个数字,那么统计数组对于的位置就统计一下 28 tempArr[shu][count[shu]++] = arr[j]; 29 } 30 //我们遍历统计数组,取出二维数组中的元素,放回原数组 31 int index = 0; 32 for (int k = 0; k < count.length; k++) { 33 if (count[k] != 0) { 34 for (int h = 0; h < count[k]; h++) { 35 arr[index] = tempArr[k][h]; 36 index++; 37 } 38 //一轮过后统计的个数 39 count[k] = 0; 40 } 41 } 42 } 43 44 45 } 46 47 private static int getMax(int[] arr) { 48 int max=arr[0]; 49 for (int i = 1; i < arr.length; i++) { 50 if(arr[i]>max){ 51 max=arr[i]; 52 } 53 } 54 return max; 55 } 56 }
八、堆排序:
思想:初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。然后将根节点与堆的最后一个节点交换。然后对前面(n-1)个数重新调整使之成为堆。依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。所以堆排序有两个函数组成。一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
1 package com.duan.array; 2 3 import java.util.Arrays; 4 5 public class HeapSort { 6 public static void main(String[] args) { 7 int[] nums = {16,7,3,20,17,8}; 8 headSort(nums); 9 for (int num : nums) { 10 System.out.print(num + " "); 11 } 12 } 13 14 /** 15 * 堆排序 16 */ 17 public static void headSort(int[] list) { 18 //构造初始堆,从第一个非叶子节点开始调整,左右孩子节点中较大的交换到父节点中 19 for (int i = (list.length) / 2 - 1; i >= 0; i--) { 20 headAdjust(list, list.length, i); 21 } 22 //排序,将最大的节点放在堆尾,然后从根节点重新调整 23 for (int i = list.length - 1; i >= 1; i--) { 24 int temp = list[0]; 25 list[0] = list[i]; 26 list[i] = temp; 27 headAdjust(list, i, 0); 28 } 29 } 30 31 private static void headAdjust(int[] list, int len, int i) { 32 int k = i, temp = list[i], index = 2 * k + 1; 33 while (index < len) { 34 if (index + 1 < len) { 35 if (list[index] < list[index + 1]) { 36 index = index + 1; 37 } 38 } 39 if (list[index] > temp) { 40 list[k] = list[index]; 41 k = index; 42 index = 2 * k + 1; 43 } else { 44 break; 45 } 46 } 47 list[k] = temp; 48 } 49 }