1、转换字符串的类
1 /** 2 * 排序后组成字符串 3 */ 4 public class ArrayToString { 5 public static String arrayToString(int[] arr) { 6 StringBuilder sb = new StringBuilder(); 7 sb.append("["); 8 for (int i = 0; i < arr.length; i++) { 9 if (i == arr.length - 1) { 10 sb.append(arr[i]); 11 } else { 12 sb.append(arr[i]).append(","); 13 } 14 } 15 sb.append("]"); 16 String s = sb.toString(); 17 return s; 18 } 19 }
2、冒泡排序
1 /** 2 * 冒泡排序 3 * 原理: 4 * 1、比较相邻的元素。如果第一个比第二个大,就交换他们两个。 5 * 2、对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这之后,最后的元素应该会是最大的数。 6 * 3、针对所有的元素重复以上的步骤,除了最后一个。 7 * 4、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 8 */ 9 public class MaoPao { 10 public static void main(String[] args) { 11 12 int[] arr = {27, 12, 34, 22, 11}; 13 System.out.println("冒泡排序前:" + arrayToString(arr)); 14 15 for (int i = 0; i < arr.length; i++) { 16 for (int j = 0; j < arr.length - 1 - i; j++) {//第一次比较4次,第二次比较3次,以此类推,共需要比较arr.length - 1次 17 if (arr[j] > arr[j + 1]) { 18 int temp = arr[j]; 19 arr[j] = arr[j + 1]; 20 arr[j + 1] = temp; 21 } 22 } 23 } 24 System.out.println("冒泡排序后:" + arrayToString(arr)); 25 } 26 }
3、插入排序
1 /** 2 * 插入排序 3 * 原理: 4 * 1.从第一个元素开始,该元素可以认为已经被排序; 5 * 2.取出下一个元素,在已经排序的元素序列中从后向前扫描; 6 * 3.如果该元素(已排序)大于新元素,将该元素移到下一位置; 7 * 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置; 8 * 5.将新元素插入到该位置后; 9 * 6.重复步骤2-5。 10 */ 11 public class ChaRu { 12 public static void main(String[] args) { 13 int[] arr = {27, 12, 34, 22, 11}; 14 System.out.println("排序前:" + arrayToString(arr)); 15 16 for (int i = 0; i < arr.length; i++) { 17 for (int j = i; j > 0; j--) { 18 if (arr[j] < arr[j - 1]) { 19 int temp = arr[j - 1]; 20 arr[j - 1] = arr[j]; 21 arr[j] = temp; 22 } 23 } 24 } 25 System.out.println("排序后:" + arrayToString(arr)); 26 } 27 }
4、选择排序
1 /** 2 * 选择排序 3 * 原理: 4 * 1.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。 5 * 2.再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。 6 * 3.重复第二步,直到所有元素均排序完毕。 7 */ 8 public class XuanZe { 9 public static void main(String[] args) { 10 int[] arr = new int[]{1, 6, 8, 9, 2, 3, 5, 4, 7}; 11 System.out.println("排序前:" + arrayToString(arr)); 12 13 for (int i = 0; i < arr.length - 1; i++) {//每次循环都会找出最小的数 14 int minIndex = i;//记录最小数的下标 15 int minNum = arr[i];//记录最小数 16 for (int j = i + 1; j < arr.length; j++) {//每次循环都会找出最小的数 17 if (arr[j] < minNum) {//如果当前数比最小数小,则更新最小数 18 minNum = arr[j];//更新最小数 19 minIndex = j;//更新最小数的下标 20 } 21 } 22 arr[minIndex] = arr[i];//将最小数放到最前面 23 arr[i] = minNum;//将标志位放到最小数原来所在的位置 24 } 25 System.out.println("排序后:" + arrayToString(arr)); 26 } 27 }
5、希尔排序
1 /** 2 * 希尔排序 3 * 原理: 4 * 1.选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1; 5 * 2.按增量序列个数 k,对序列进行 k 趟排序; 6 * 3.每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。 7 */ 8 public class XiEr { 9 public static void main(String[] args) { 10 int[] arr = new int[]{8, 9, 1, 7, 2, 3, 5, 4, 6, 0}; 11 System.out.println("希尔排序前:" + arrayToString(arr)); 12 13 ShellSort_swap(arr); 14 // ShellSort_move(arr); 15 System.out.println("希尔排序后:" + arrayToString(arr)); 16 17 } 18 19 20 //交换式希尔排序 21 public static void ShellSort_swap(int[] arr) { 22 int temp = 0; 23 for (int gap = arr.length / 2; gap > 0; gap /= 2) { 24 for (int i = gap; i < arr.length; i++) { 25 //步长为5(每组有两个元素) 26 for (int j = i - gap; j >= 0; j -= gap) { 27 //如果当前元素大于加上步长后的那个元素,则交换 28 if (arr[j] > arr[j + gap]) { 29 temp = arr[j]; 30 arr[j] = arr[j + gap]; 31 arr[j + gap] = temp; 32 } 33 } 34 } 35 } 36 }
6、归并排序
1 /** 2 * 归并排序 3 * 原理: 4 * 1、将一个数组拆分为两个,从中间点拆开,通过递归操作来实现一层一层拆分。 5 * 2、从左右数组中选择小的元素放入到临时空间,并移动下标到下一位置。 6 * 3、重复步骤2直到某一下标达到尾部。 7 * 4、将另一序列剩下的所有元素依次放入临时空间。 8 * 5、将临时空间的数据依次放入原数据数组。 9 */ 10 public class GuiBing { 11 public static void main(String[] args) { 12 // int[] arr = {1}; 13 int[] arr = {1, 4, 7, 8, 3}; 14 // int[] arr = {3, 0, 6, 4, 1, 3, 7, 8, 5, 9}; 15 System.out.println("归并排序前:" + arrayToString(arr)); 16 sort(arr, 0, arr.length - 1); 17 System.out.println("归并排序后:" + arrayToString(arr)); 18 } 19 20 public static void sort(int[] arr, int left, int right) { 21 if (left == right) { 22 // System.out.println(right); 23 return; 24 } 25 //分成两半 26 int mid = left + (right - left) / 2; 27 //左边排序 28 sort(arr, left, mid); 29 //右边排序 30 // System.out.println(right); 31 sort(arr, mid + 1, right); 32 33 merge(arr, left, mid + 1, right); 34 } 35 36 /** 37 * @param arr 38 * @param leftPtr 数组最左边 39 * @param rightBound 数组中间 40 * @param rightPtr 数组最右边 41 */ 42 static void merge(int[] arr, int leftPtr, int rightBound, int rightPtr) { 43 int mid = rightBound - 1; 44 int[] temp = new int[rightPtr - leftPtr + 1]; 45 46 int i = leftPtr; 47 int j = rightBound; 48 int k = 0; 49 50 while (i <= mid && j <= rightPtr) { 51 if (arr[i] <= arr[j]) { 52 temp[k] = arr[i]; 53 i++; 54 k++; 55 } else { 56 temp[k] = arr[j]; 57 j++; 58 k++; 59 } 60 } 61 62 // 将右边剩余的归并 63 while (i <= mid) { 64 temp[k++] = arr[i++]; 65 } 66 //将左边剩余的归并 67 while (j <= rightPtr) { 68 temp[k++] = arr[j++]; 69 70 } 71 72 for (int m = 0; m < temp.length; m++) { 73 arr[leftPtr + m] = temp[m]; 74 } 75 } 76 }
7、快速排序
1 /** 2 * 快速排序 3 * 原理: 4 * 1.先从数列中取出一个数作为基准数。 5 * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。 6 * 3.再对左右区间重复第二步,直到各区间只有一个数。 7 * 虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤。 8 * 因此我的对快速排序作了进一步的说明:挖坑填数+分治法 9 */ 10 public class KuaiSu { 11 public static void main(String[] args) { 12 int[] arr = {56, 12, 45, 34, 67, 1, 78, 90, 68, 14}; 13 System.out.println("快速排序前:" + arrayToString(arr)); 14 15 quickSort(arr,0,arr.length - 1); 16 System.out.println("快速排序后:"+arrayToString(arr)); 17 } 18 19 /** 20 * 分区过程 21 * a[] 待分区数组 22 * left 待分区数组最小下标 23 * right 待分区数组最大下标 24 */ 25 public static void quickSort(int[] a,int left,int right) { 26 if(left<right) { 27 int temp = qSort(a, left, right); 28 quickSort(a,left,temp-1); 29 quickSort(a,temp+1,right); 30 } 31 } 32 /** 33 * 排序过程 34 * a 待排序数组 35 * left 待排序数组最小下标 36 * right 待排序数组最大下标 37 * @return 排好序之后基准数的位置下标,方便下次的分区 38 */ 39 public static int qSort(int[] a,int left,int right) { 40 int temp=a[left];//定义基准数,默认为数组的第一个元素 41 while(left<right) {//循环执行的条件 42 //因为默认的基准数是在最左边,所以首先从右边开始比较进入while循环的判断条件 43 //如果当前arr[right]比基准数大,则直接将右指针左移一位,当然还要保证left<right 44 while(left<right && a[right]>temp) { 45 right--; 46 } 47 //跳出循环说明当前的arr[right]比基准数要小,那么直接将当前数移动到基准数所在的位置,并且左指针向右移一位(left++) 48 //这时当前数(arr[right])所在的位置空出,需要从左边找一个比基准数大的数来填充。 49 if(left<right) { 50 a[left++]=a[right]; 51 } 52 //下面的步骤是为了在左边找到比基准数大的数填充到right的位置。 53 //因为现在需要填充的位置在右边,所以左边的指针移动,如果arr[left]小于或者等于基准数,则直接将左指针右移一位 54 while(left<right && a[left]<=temp) { 55 left++; 56 } 57 //跳出上一个循环说明当前的arr[left]的值大于基准数,需要将该值填充到右边空出的位置,然后当前位置空出。 58 if(left<right) { 59 a[right--]=a[left]; 60 } 61 } 62 //当循环结束说明左指针和右指针已经相遇。并且相遇的位置是一个空出的位置, 63 //这时候将基准数填入该位置,并返回该位置的下标,为分区做准备。 64 a[left]=temp; 65 return left; 66 } 67 }
8、桶排序
1 /** 2 * 桶排序 3 * 原理: 4 * 1、遍历原始数组,找到数组中的最大值 5 * 2、创建一个下标为原始数组中最大值的桶数组,该桶数组的下标代表元素,该数组下标所对应的值代表这个值出现的次数 6 * 3、再次遍历原始数组,得到原数组中存在的各个元素,以及出现的次数 7 * 4、遍历桶数组,外层循环从桶的第一位开始(即下表为零);内层循环遍历桶数组中下标为i的值出现的次数 8 */ 9 public class Tong { 10 public static void main(String[] args) { 11 int[] arr = {3, 4, 1, 3, 2, 5, 4, 2, 7, 0}; 12 System.out.println("桶排序前:" + arrayToString(arr)); 13 bucketSort(arr); 14 System.out.println("桶排序后:" + arrayToString(arr)); 15 } 16 17 public static void bucketSort(int[] num) { 18 19 // 遍历原始数组,找到数组中的最大值 20 int max = num[0]; 21 for (int i = 0; i < num.length; i++) { 22 if (num[i] > max) { 23 max = num[i]; 24 } 25 } 26 27 // 创建一个下标为原始数组中最大值的桶数组,该桶数组的下标代表元素,该数组下标所对应的值代表这个值出现的次数 28 int[] bucketArray = new int[max + 1]; 29 30 // 再次遍历原始数组,得到原数组中存在的各个元素,以及出现的次数 31 for (int i = 0; i < num.length; i++) { 32 bucketArray[num[i]]++; 33 } 34 35 // 遍历桶数组,外层循环从桶的第一位开始(即下表为零);内层循环遍历桶数组中下标为i的值出现的次数 36 int index = 0; 37 for (int i = 0; i < bucketArray.length; i++) { 38 for (int j = 0; j < bucketArray[i]; j++) { 39 num[index++] = i; 40 } 41 } 42 } 43 }
9、基数排序
1 /** 2 * 基数排序(利用基本原理进行排序) 3 * 原理: 4 * 1.取得数组中的最大数,并取得位数; 5 * 2.arr为原始数组,从最低位开始取每个位组成radix数组; 6 * 3.对radix进行计数排序(利用计数排序适用于小范围数的特点)。 7 */ 8 public class Base { 9 public static void main(String[] args) { 10 int[] arr = {134, 256, 12, 54, 756}; 11 System.out.println("基数排序前:" + arrayToString(arr)); 12 radixSort(arr); 13 System.out.println("基数排序后:" + arrayToString(arr)); 14 } 15 16 public static void radixSort(int[] arr) { 17 18 int max = arr[0];//假设第一个数就是最大数 19 for (int i = 1; i < arr.length; i++) { 20 if (arr[i] > max) { 21 max = arr[i]; 22 } 23 } 24 int maxLength = (max + " ").length(); 25 //第一轮(针对每个元素的个位进行排序处理) 26 27 //定义一个二维数组,表示10个桶,每个桶就是一维数组 28 //说明: 29 //1.二维数组包含10个一维数组 30 //2.为了防止在放入数的时候,数据溢出,则每个一个数组(桶),大小定为arr.length 31 //3明显,基数排序是使用空间换时间 32 int[][] bucket = new int[10][arr.length]; 33 34 //为了记录每个桶中,实际存放了多少个数据,我们定义了一个一维数组来记录各个桶中的个数 35 int[] bucketElementCounts = new int[10]; 36 37 for (int i = 0, n = 1; i < maxLength; i++, n *= 10) { 38 for (int j = 0; j < arr.length; j++) { 39 //取出每个元素的对应位的值进行排序处理,第一次是个位,第二次是十位。。。 40 int digitOfElement = arr[j] / n % 10; 41 //放入到对应的桶中 42 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j]; 43 bucketElementCounts[digitOfElement]++; 44 } 45 46 //按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组) 47 int index = 0; 48 //遍历每一桶,并将桶中的数据,放入到原数组 49 for (int k = 0; k < bucketElementCounts.length; k++) { 50 //如果桶中,有数据,我们才能放入到原数组 51 if (bucketElementCounts[k] != 0) { 52 //循环该桶即第k个桶,(即第k个一维数组),放入 53 for (int l = 0; l < bucketElementCounts[k]; l++) { 54 //取出元素放入arr 55 arr[index] = bucket[k][l]; 56 index++; 57 } 58 } 59 //第i+1轮处理后,需要将每个bucketElementCounts[k]=0!!! 60 bucketElementCounts[k] = 0; 61 } 62 } 63 } 64 }
10、计数排序
1 /** 2 * 计数排序 3 * 原理: 4 * https://blog.csdn.net/allway2/article/details/114003894 5 */ 6 import static com.itheima08.paixu.ArrayToString.arrayToString; 7 8 public class JiShu { 9 public static void main(String[] args) { 10 int[] array = {0, 2, 2, 1, 4, 4, 5, 1, 7}; 11 System.out.println("计数排序前:" + arrayToString(array)); 12 int max = findMaxElement(array);//找数组中最大数 13 System.out.println("数组中最大数是:" + max); 14 int[] after = countingSort(array, max + 1); 15 System.out.println("计数排序后:" + arrayToString(after)); 16 } 17 18 private static int findMaxElement(int[] array) { 19 int max = array[0]; 20 for (int val : array) { 21 if (val > max) max = val; 22 } 23 return max; 24 } 25 26 private static int[] countingSort(int[] array, int range) { 27 int[] output = new int[array.length]; 28 int[] count = new int[range]; 29 // Calculate frequency of each element, put it in count array 30 for (int i = 0; i < array.length; i++) { 31 count[array[i]]++; 32 } 33 System.out.println("计数数组是:" + arrayToString(count)); 34 35 // Modify count array to get the final position of elements 36 for (int i = 1; i < range; i++) { 37 count[i] = count[i] + count[i - 1]; 38 } 39 System.out.println("统计总数数组是:" + arrayToString(count)); 40 41 // Add elements to output sorted array 42 for (int i = 0; i < array.length; i++) { 43 output[count[array[i]] - 1] = array[i]; 44 count[array[i]]--; 45 } 46 return output; 47 } 48 }
11、堆排序(大顶堆和小顶堆)
1)大顶堆
1 /** 2 * 堆排序(升序:大顶堆) 3 * 原理: 4 * 1、根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。 5 * 2、每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。 6 */ 7 public class BigDui { 8 public static void main(String[] args) { 9 int[] arr = {6, 2, 7, 4, 1, 9, 3}; 10 System.out.println("大顶堆排序前:" + arrayToString(arr)); 11 12 sort(arr); 13 System.out.println("大顶堆排序后:" + arrayToString(arr)); 14 } 15 16 public static void sort(int[] arr) { 17 //1.构建大顶堆 18 for (int i = arr.length / 2 - 1; i >= 0; i--) { 19 //从第一个非叶子结点从下至上,从右至左调整结构 20 adjustHeap(arr, i, arr.length); 21 } 22 //2.调整堆结构+交换堆顶元素与末尾元素 23 for (int j = arr.length - 1; j > 0; j--) { 24 swap(arr, 0, j);//将堆顶元素与末尾元素进行交换 25 adjustHeap(arr, 0, j);//重新对堆进行调整 26 } 27 28 } 29 30 /** 31 * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上) 32 * 33 * @param arr 34 * @param i 35 * @param length 36 */ 37 public static void adjustHeap(int[] arr, int i, int length) { 38 int temp = arr[i];//先取出当前元素i 39 for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//从i结点的左子结点开始,也就是2i+1处开始 40 if (k + 1 < length && arr[k] < arr[k + 1]) {//如果左子结点小于右子结点,k指向右子结点 41 k++; 42 } 43 if (arr[k] > temp) {//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换) 44 arr[i] = arr[k]; 45 i = k; 46 } else { 47 break; 48 } 49 } 50 arr[i] = temp;//将temp值放到最终的位置 51 } 52 53 /** 54 * 交换元素 55 * 56 * @param arr 57 * @param a 58 * @param b 59 */ 60 public static void swap(int[] arr, int a, int b) { 61 int temp = arr[a]; 62 arr[a] = arr[b]; 63 arr[b] = temp; 64 } 65 }
2)小顶堆
1 /** 2 * 堆排序:(降序:小顶堆) 3 * 原理: 4 * 1、根据初始数组去构造初始堆(构建一个完全二叉树,保证所有的父结点都比它的孩子结点数值大)。 5 * 2、每次交换第一个和最后一个元素,输出最后一个元素(最大值),然后把剩下元素重新调整为大根堆。 6 */ 7 public class SmallDui { 8 public static void main(String[] args) { 9 int[] arr = {-5, 6, 2, 7, 4, 1, 9, 3, -1}; 10 System.out.println("小顶堆排序前:" + arrayToString(arr)); 11 12 sort(arr); 13 System.out.println("小顶堆排序后:" + arrayToString(arr)); 14 } 15 16 public static void sort(int[] arr) { 17 //1.构建小顶堆 18 for (int i = arr.length / 2 - 1; i >= 0; i--) { 19 //从第一个非叶子结点从下至上,从右至左调整结构 20 adjustHeap(arr, i, arr.length); 21 } 22 //2.调整堆结构+交换堆顶元素与末尾元素 23 for (int j = arr.length - 1; j > 0; j--) { 24 swap(arr, 0, j);//将堆顶元素与末尾元素进行交换 25 adjustHeap(arr, 0, j);//重新对堆进行调整 26 } 27 } 28 29 /** 30 * 调整小顶堆(仅是调整过程,建立在小顶堆已构建的基础上) 31 * 32 * @param arr 33 * @param i 34 * @param length 35 */ 36 public static void adjustHeap(int[] arr, int i, int length) { 37 int temp = arr[i];//先取出当前元素i 38 for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {//从i结点的左子结点开始,也就是2i+1处开始 39 if (k + 1 < length && arr[k] > arr[k + 1]) {//如果左子结点大于右子结点,k指向右子结点 40 k++; 41 } 42 if (arr[k] < temp) {//如果子节点小于父节点,将子节点值赋给父节点(不用进行交换) 43 arr[i] = arr[k]; 44 i = k; 45 } else { 46 break; 47 } 48 } 49 arr[i] = temp;//将temp值放到最终的位置 50 } 51 52 /** 53 * 交换元素 54 * 55 * @param arr 56 * @param a 57 * @param b 58 */ 59 public static void swap(int[] arr, int a, int b) { 60 int temp = arr[a]; 61 arr[a] = arr[b]; 62 arr[b] = temp; 63 } 64 }
注:仅用于学习
标签:arr,十大,int,算法,length,数组,排序,public From: https://www.cnblogs.com/it-java-ls/p/17029203.html