javaSE基础知识——day13 八种排序冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、基数排序
2019-07-13 22:28
246 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/lalaMarry/article/details/95801444
冒泡排序
冒泡排序:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。
案例:
import java.util.Arrays; public class ArraySortDemo { public static void main(String[] args) { //冒泡排序:元素两两比较,大的往后放,经过一轮比较后,那么最大的元素就会出现在最后面。 //定义原始数组 int[] arr = {24, 69, 80, 57, 13,1,4,6,-1}; //tuiDao(arr); for (int j = 0; j <arr.length-1; j++) { for (int i = 0; i < arr.length - 1-j; i++) { //比较大小,把大的往后放 if (arr[i] > arr[i + 1]) { int t = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = t; } } } System.out.println(Arrays.toString(arr)); } private static void tuiDao(int[] arr) { //第一轮比较4次 for (int i = 0; i < arr.length-1; i++) { //比较大小,把大的往后放 if(arr[i]>arr[i+1]){ int t=arr[i]; arr[i]=arr[i+1]; arr[i + 1]=t; } } //第二轮比较3次 for (int i = 0; i < arr.length - 1-1; i++) { //比较大小,把大的往后放 if (arr[i] > arr[i + 1]) { int t = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = t; } } //第三比较2次 for (int i = 0; i < arr.length - 1 - 1-1; i++) { //比较大小,把大的往后放 if (arr[i] > arr[i + 1]) { int t = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = t; } } //第四轮比较 for (int i = 0; i < arr.length - 1 - 1 - 1-1; i++) { //比较大小,把大的往后放 if (arr[i] > arr[i + 1]) { int t = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = t; } } } }
选择排序
每次拿一个元素,跟他后面的元素,挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去
案例:
import java.util.Arrays; public class ArraySortDemo2 { public static void main(String[] args) { //选择排序:每次拿一个元素,跟他后面的元素,挨个去比,小的往前放,经过一轮比较后,那么最小元素就会放在最前面去 int[] arr = {24, 69, 80, 57, 13, 4, 6, 90, -1}; // tuiDao(arr); for (int index = 0; index < arr.length - 1; index++) { for (int i = 1 + index; i < arr.length; i++) { if (arr[index] > arr[i]) { swapValue(arr, index, i); } } } System.out.println(Arrays.toString(arr)); } private static void tuiDao(int[] arr) { //第一轮比较 int index = 0; //先拿第一个元素 跟后面的元素挨个去比 for (int i = 1; i < arr.length; i++) { if (arr[index] > arr[i]) { swapValue(arr, index, i); } } //第二轮比较 index = 1; //先拿第一个元素 跟后面的元素挨个去比 for (int i = 1 + index; i < arr.length; i++) { if (arr[index] > arr[i]) { swapValue(arr, index, i); } } //第三轮 index = 2; //先拿第一个元素 跟后面的元素挨个去比 for (int i = 1 + index; i < arr.length; i++) { if (arr[index] > arr[i]) { swapValue(arr, index, i); } } //第三轮 index = 3; //先拿第一个元素 跟后面的元素挨个去比 for (int i = 1 + index; i < arr.length; i++) { if (arr[index] > arr[i]) { swapValue(arr, index, i); } } } //值交换的方法 private static void swapValue(int[] arr, int j, int i) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } }
插入排序
直接插入排序:将后面的元素,插入之前的一个有序列表,使之仍然保持有序
案例:
import java.util.Arrays; public class ArrayDemo { public static void main(String[] args) { //直接插入排序:将后面的元素,插入之前的一个有序列表,使之仍然保持有序 int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150}; // sortDemo1(arr); for (int i = 1; i < arr.length; i++) { for (int j = i; j > 0; j--) { if (arr[j] < arr[j - 1]) { swapValue(arr, j, j - 1); } } } System.out.println(Arrays.toString(arr)); } //值交换的方法 private static void swapValue(int[] arr, int j, int i) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } private static void sortDemo1(int[] arr) { //外层循环定义轮次 for (int i = 1; i < arr.length; i++) { //里层就是循环让当前元素和上一个有序列表中的每个元素,比较,进行位置交换,使之仍保持有序 int j = i; while (j > 0 && arr[j] < arr[j - 1]) { int t = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = t; j--; } } } }
希尔排序
希尔排序,是对直接插入排序的一种改进,他的思想选择一个合适的增量,然后经过一轮插入排序后,就会让数组大致有序
然后不断的缩小增量,进行插入排序,直到增量为1 整个排序结束
案例:
import java.util.Arrays; public class ArryDemo2 { public static void main(String[] args) { //希尔排序,是对直接插入排序的一种改进,他的思想选择一个合适的增量,然后经过一轮插入排序后,就会让数组大致有序 //然后不断的缩小增量,进行插入排序,直到增量为1 整个排序结束 int[] arr = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1}; shellSort(arr); //其实我们的直接插入排序,就是增量为1的希尔排序 //int h = 1; //for (int i = h; i < arr.length; i++) { // for (int j = i; j > h - 1; j -= h) { // if (arr[j] < arr[j - h]) { // swapValue(arr, j, j - h); // } // } //} System.out.println(Arrays.toString(arr)); } private static void shellSort(int[] arr) { //定义增量为4 /* int h=4; for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j-=h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } } h = 2; for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j -= h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } } h = 1; for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j -= h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } }*/ //间隔选为4 不是很合理 /* for (int h = 4; h>0; h/=2) { for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j -= h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } } }*/ //间隔得选取合理 :一般第一次的增量我们选取数组长度的一半 /* for (int h = arr.length/2; h > 0; h /= 2) { for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j -= h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } } } */ //克努特序列 //int h=1; //h=3*h+1; // 1,4,13,40,121,364 //我要选择一个合适的增量 使用克努特序列来选 int jianGe = 1; while (jianGe <= arr.length / 3) { jianGe = 3 * jianGe + 1; } for (int h = jianGe; h > 0; h = (h - 1) / 3) { for (int i = h; i < arr.length; i++) { for (int j = i; j > h - 1; j -= h) { if (arr[j] < arr[j - h]) { swapValue(arr, j, j - h); } } } } } //值交换的方法 private static void swapValue(int[] arr, int j, int i) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } }
归并排序
案例:
import java.util.Arrays; public class ArrayDemo3 { public static void main(String[] args) { int[] arr = {2, 10, 1, 0, 100, 3, 5, -1, 200, 109, 30, 1009, 109, 109, -100}; //int[] arr={1,3,5,7,9,0,2,4,8,10}; //归并排序 //分 chaiFen(arr, 0, arr.length - 1); //归 // mergerSort(arr,0,(arr.length/2)-1,arr.length-1); System.out.println(Arrays.toString(arr)); } private static void chaiFen(int[] arr, int startIndex, int endIndex) { //计算中间索引 int centerIndex = (startIndex + endIndex) / 2; //递归来拆 if (startIndex < endIndex) { //拆分左边 chaiFen(arr, startIndex, centerIndex); //拆分右边 chaiFen(arr, centerIndex + 1, endIndex); //归并 mergerSort(arr, startIndex, centerIndex, endIndex); } } /** * @param arr 要归并的数组 * @param startIndex 起始索引 * @param centerIndex 中间索引 * @param endIndex 结束索引 */ private static void mergerSort(int[] arr, int startIndex, int centerIndex, int endIndex) { //定义一个临时数组 int[] tempArray = new int[endIndex - startIndex + 1]; //定义临时数组的起始索引 int index = 0; //定义左边数组的起始索引 int i = startIndex; //定义右边数组的起始索引 int j = centerIndex + 1; //循环比较左右两边数组的元素,往临时数组里面方法 while (i <= centerIndex && j <= endIndex) { //进来比较 if (arr[i] <= arr[j]) { tempArray[index] = arr[i]; i++; //记得递增索引 } else { tempArray[index] = arr[j]; j++;//记得递增索引 } index++; //临时数组的索引 } //处理左边剩余元素 while (i <= centerIndex) { tempArray[index] = arr[i]; i++; //记得递增索引 index++; } //处理右边剩余元素 while (j <= endIndex) { tempArray[index] = arr[j]; j++; //记得递增索引 index++; } //这个时候我们的临时数组里面的元素已经排序好了 // System.out.println(Arrays.toString(tempArray)); //遍历临时数组,将临时数组中的元素,放到原数组里面去 for (int k = 0; k < tempArray.length; k++) { arr[k + startIndex] = tempArray[k]; } } }
快速排序
案例:
import java.util.Arrays; public class MyTest { public static void main(String[] args) { int[] arr = {2, 1, 0, 6, 9, 0, 10, 100, 20, 10, -1, 3, 6, 100, 200, 150}; QuickSortUtils.quickSort(arr,0,arr.length-1); System.out.println(Arrays.toString(arr)); } }
import java.time.Instant; public class QuickSortUtils { private QuickSortUtils() { } /** * * @param arr 要排序的数组 * @param startIndex 开始索引 * @param endIndex 结束索引 */ public static void quickSort(int[] arr,int startIndex,int endIndex){ if(startIndex<endIndex){ //找到基准数的索引 int index=getIndex(arr,startIndex,endIndex); //对左右两边进行递归调用 quickSort(arr,startIndex,index); quickSort(arr,index+1,endIndex); } } // //将基准数挖出形成第一个坑。 //由后向前找比他小的数,找到后挖出此数填到前一个坑中。 //由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中。 //再重复执行2,3两步骤。 //挖坑填数 private static int getIndex(int[] arr, int startIndex, int endIndex) { //定义三个变量 int i=startIndex; int j=endIndex; //定义基准数 int x=arr[i]; while (i<j){ //1. 由后向前找比他小的数,找到后挖出此数填到前一个坑中。 while (i<j&&arr[j]>=x){ j--; } //填坑 if(i<j){ arr[i]=arr[j]; i++;//顺便让i增一下 } //2,由前向后找比他大或等于的数,找到后也挖出此数填到前一个坑中 while (i<j&&arr[i]<x){ i++; } //填坑 if (i < j) { arr[j] = arr[i]; j--; //顺便让j减一下 } } //以上循环完毕之后,将基准数填到最后一个坑里面去 arr[i]=x; return i; } }
基数排序
案例:
import java.util.Arrays; public class 基数排序算法 { public static void main(String[] args) { int[] arr = {1, 9, 8, 12, 23, 28, 32, 42, 102, 100, 259}; sortArray(arr); System.out.println(Arrays.toString(arr)); } private static void sortArray(int[] arr) { //定义一个二维数组 int[][] tempArr = new int[10][arr.length];//里面的一维数组的长度最大就和待排序的数组长度一样 //定义一个统计的一维数组,可以统计二维数组每个桶中放了多少数字 int[] counts = new int[10];//长度和二维数组长度保持一样 //获取数组中最大的数 int max = getMax(arr); //计算数组中最大的数的有几位,这就是我们需要比较的轮次 int len = String.valueOf(max).length(); for (int i = 0, n = 1; i < len; i++, n *= 10) { for (int j = 0; j < arr.length; j++) { //获取每个位上的数字 int ys = arr[j] / n % 10; //我们找一个二维数组,数组中放10个桶,这个桶就是一位数组 // counts[ys]++ 意思是,二维数组的桶中放一个数字,那么统计数组对于的位置就统计一下 tempArr[ys][counts[ys]++] = arr[j]; } //我们遍历统计数组,取出二维数组中的元素,放回原数组 int index = 0; for (int k = 0; k < counts.length; k++) { if (counts[k] != 0) { for (int h = 0; h < counts[k]; h++) { arr[index] = tempArr[k][h]; index++; } //情况一轮过后统计的个数 counts[k] = 0; } } } } private static int getMax(int[] arr) { int max = arr[0]; for (int i = 0; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } }
import java.util.Arrays; import java.util.SortedMap; import static java.util.Arrays.sort; public class ArrayDemo2 { public static void main(String[] args) { //基数排序 int[] arr = {21,31,444,23,33,47,1000,900,124,987,0,100,0}; //int max=getMax(arr); sortArr(arr); System.out.println(Arrays.toString(arr)); } private static void sortArr(int[] arr) { //最大数有几位,我们就排几轮 int max = getMax(arr); int len = String.valueOf(max).length(); //len=2; //定义一个二维数组,长度为10 int[][] tempArr = new int[10][arr.length]; //再定义一个数组,长度和二维数组的长度一样,用于记录二维数组中的每一个桶位存了几个数字 int[] counts = new int[10]; for (int i = 0, n = 1; i < len; i++, n *= 10) { //循环遍历,取每个位上的数字 for (int j = 0; j < arr.length; j++) { //取每个位上的数字 int ys = arr[j] / n % 10; //int count=counts[ys]; tempArr[ys][counts[ys]]=arr[j]; counts[ys]++; // count++;//二维数组中的一维数组放了要一个数,就在统计数组对应的位置统计一下 // counts[ys] = count; //将累加后的值,赋值给统计数组 } //取出每个桶中的元素,放入原来的数组 int index=0; for (int k = 0; k < counts.length; k++) { //取出统计数组在每个位置上统计的个数 if(counts[k]!=0){ for (int h = 0; h < counts[k]; h++) { arr[index]=tempArr[k][h]; index++; } counts[k] = 0; //一趟完成后,把统计的个数清0 } } } //for (int i = 0; i < tempArr.length; i++) { // System.out.println(Arrays.toString(tempArr[i])); //} } private static int getMax(int[] arr) { int max = arr[0]; for (int i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } return max; } }
相关文章推荐
- 基本排序算法(冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 希尔排序)
- C# 插入排序 冒泡排序 选择排序 快速排序 堆排序 归并排序 基数排序 希尔排序
- 插入排序、冒泡排序、选择排序、希尔排序、快速排序、归并排序、堆排序和LST基数排序——C++实现
- 各种排序算法总结----基数排序、归并排序、插入排序、冒泡排序、选择排序、快速排序、堆排序、希尔排序
- 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 经典排序算法设计与分析(插入排序、冒泡排序、选择排序、shell排序、快速排序、堆排序、分配排序、基数排序、桶排序、归并排序)
- 归并排序,堆排序,基数排序,希尔排序,快速排序,交换排序,选择排序和插入排序的总结和比较
- 常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)
- 各种常见的排序,冒泡排序,选择排序,插入排序,希尔排序,堆排序,快速排序,基数排序,桶排序
- 排序算法(冒泡排序、选择排序、插入排序、归并排序、快速排序、希尔排序)
- 【程序员笔试面试必会——排序①】Python实现 冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序
- 几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现
- 冒泡排序,插入排序,选择排序,希尔排序,归并排序,快速排序
- 数据结构与算法从零开始系列:冒泡排序、选择排序、插入排序、希尔排序、堆排序、快速排序、归并排序、基数排序
- python数据结构:冒泡排序,选择排序,插入排序,希尔排序(进阶的插入排序),快速排序,归并排序
- 直通BAT-排序1(冒泡排序、选择排序、插入排序、归并排序、快速排序、堆排序、希尔排序)
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)