数据结构相关的内容在这里。
package sort; import java.util.Arrays; public class ArraySorter { /** * int数组的排序工具 复习五种排序方法: 交换排序 插入排序 选择排序 归并排序 分配排序 * 相应方法都是用来复习面试的,不讨论数据量和数据大小等问题 * 菜鸟收集整理之作 * @author Peter Zhang */ //private static int[] arr = { 5, 9, 8, 7, 2, 4, 1, 3, 0, 6 };//待测数组 private static int[] arr = {1234,5425,38,35,46,13,89,356,123,78963,51,62}; public static void main(String[] args) { System.out.println("待测数组"); print(arr); //Arrays.sort(arr); bubbleSort(arr); //bubbleSort2(arr); // quickSort(arr); // insertSort(arr); // shellSort(arr); // shellSort2(arr); // selectSort(arr); // heapSort(arr); // mergeSort(arr); //radixSort(arr); //radixSort2(arr); print(arr); } // 显示打印的方法 private static void print(int[] arr) { for (int i : arr) { System.out.print(i + " "); } System.out.println(); } // 交换元素的方法 private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } // 交换排序 /** * 冒泡排序 数组中相邻左右两个元素相互比较,大的向后 * * @param arr */ public static void bubbleSort2(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = i + 1; j < arr.length - 1; j++) { if (arr[i] > arr[j]) { swap(arr, i, j); } } } } public static void bubbleSort(int[] arr){ for(int i=0;i<arr.length;i++){ for(int j=arr.length-1;j>i;j--){ if(arr[j] <arr[j-1]){ swap(arr, j, j-1); } } } } /** * 快速排序 选出一个关键字,比他小的放到他的左边,大的放到右边, 设置两个指针,同时与关键字进行比较。 * 先确定中间位置的数(关键字)key一般都是第一个元素以及开始元素begin和结束元素end * 再从右向左递减index,如果有元素比中间数小,就放在左边,和左边begin元素交换,begin+1 * 再从左向右递增index,如果有元素比中间数大,就放在右边,和右边的end元素交换,end+1 再递归左边和右边 * * @param arr * @param begin * @param end */ private static void quick(int[] arr, int begin, int end) { int i = begin; int j = end; if (i < j) { int key = arr[i]; while (j > i) { while (j > i && arr[j] > key) {// 右边递减寻找比关键字小的元素 j--; } if (j > i) {// 找到比关键字小的元素 下标为j arr[i++] = arr[j]; // 和左边的元素交换 左边元素递增 } while (j > i && arr[i] < key) {// 左边递增寻找比关键字大的元素 i++; } if (j > i) {// 找到比关键字大的元素 下标为i arr[j--] = arr[i]; // 再右边递减寻找比关键字小的元素 } } arr[i] = key; quick(arr, begin, j - 1);// 递归key左边 quick(arr, j + 1, end);// 递归key右边 } } // 外部方法 public static void quickSort(int[] arr) { quick(arr, 0, arr.length - 1); } // 插入排序 /** * 直接插入排序 左右分成两个部分,右边第一个元素和左边所有元素比较,小就交换,大就不变 * * @param arr */ public static void insertSort(int[] arr) { for (int i = 1; i < arr.length; i++) { for (int j = 0; j < i; j++) { if (arr[j] > arr[i]) { swap(arr, i, j); } } } } /** * 希尔排序 先设定一个增量(间隔),再根据增量分组,每个分组排序;再分组,再排序 * * @param arr */ public static void shellSort(int[] arr) { int len = arr.length; for (int increment = len / 2; increment > 0; increment /= 2) {// 分组 for (int i = increment; i < len; i++) { if (arr[i] < arr[i - increment]) {// 增量间隔的两个数,大的放后,小的放前 for (int j = 0; j < i; j += increment) { if (arr[j] > arr[i]) { swap(arr, i, j); } } } } } } public static void shellSort2(int[] arr) { int len = arr.length; int j; for (int increment = len / 2; increment > 0; increment /= 2) { for (int i = increment; i < len; i++) { int temp = arr[i]; for (j = i - increment; j >= 0 && arr[j] > temp; j -= increment) { arr[j + increment] = arr[j]; } arr[j + increment] = temp; } } } // 选择排序 /** * 直接选择排序 每次选择一个最小的 * * @param arr */ public static void selectSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { int min = i; for (int j = i + 1; j < arr.length; j++) { if (arr[min] > arr[j]) { min = j; } } if (min != i) { swap(arr, i, min); } } } /** * 堆排序 大顶堆排序 k0 k1 k2 k3 ……kn 利用大顶堆父节点比子节点大的原理, * 先构造一个大顶堆,调整它保证根节点的元素是最大的 * 交换根节点和最后一个元素,移除最后一个元素,调整length-1个元素的堆,保持结构; * 再交换此时的根节点和此时的最后一个元素,再移除此时的最后一个元素,调整剩下的堆; * 以此类推,直到就剩根节点 * * @param arr */ public static void heapSort(int[] arr) { // 创建大顶堆堆 从最后一个父节点开始向根递减 int n = arr.length - 1; // 最后一个元素的index for (int i = (n - 1) / 2; i > 0; i--) { heapify(arr, i, n);// 从最后一个根节点开始调整堆 } for (int i = n; i > 0; i--) { swap(arr, i, 0);// 交换根和最后一个元素,n-1 heapify(arr, (i - 1 - 1) / 2, i - 1);// 从最后一个根节点开始调整 } } /** * 调整堆 顶为0 左子节点为2i+1 从最后一个根节点开始调整堆的结构 * * @param arr * @param index 最后一个父节点 * @param n 最后一个元素的下标 */ private static void heapify(int[] arr, int index, int n) {// n lastIndex if (n == 0) {// 根节点 不调整 return; } for (int i = index; i >= 0; i--) { int left = 2 * i + 1;// 左子节点 if (left < n) {// 有右子节点 if (arr[left] < arr[left + 1]) { left++; // 方便在有右子节点的时候用left下标表示 } } if (arr[left] > arr[i]) {// 子节点比父节点大,交换 swap(arr, i, left); } } } // 归并排序 /** * 归并排序 把待排序序列分为若干个子序列,每个子序列是有序的, * 再把有序子序列合并为整体有序序列 * * @param arr */ public static void mergeSort(int[] arr) { merge(arr, 0, arr.length - 1); } // 分治法 自顶向下 递归分割数组并归并 private static void merge(int[] arr, int begin, int end) { if (begin < end) { int middle = (begin + end) / 2; merge(arr, begin, middle);// 分割左边部分 merge(arr, middle + 1, end);// 分割右边部分 doMerge(arr, begin, middle, end);// 归并成一个有序的区间 } } // 归并 private static void doMerge(int[] arr, int begin, int middle, int end) { int[] tmp = new int[arr.length];// 临时数组 int temp = begin;// 临时数组下标 int copy = begin;// 数组复制下标 int right = middle + 1; while (begin <= middle && right <= end) {// 两部分从左边开始互相比较 if (arr[begin] <= arr[right]) {// 小的元素放入临时数组 tmp[temp++] = arr[begin++]; } else { tmp[temp++] = arr[right++]; } } // 剩下的元素接着复制到临时数组中 while (begin <= middle) { tmp[temp++] = arr[begin++]; } while (right <= end) { tmp[temp++] = arr[right++]; } // 复制数组 while (copy <= end) { arr[copy] = tmp[copy++]; } } // 分配排序 // 基数排序 /** * int[] 单关键字十进制 基数就是10 循环装箱的次数就是数组中最大数的位数 * 用一个容量为 10*待测数组长度 的二维数组存放数据 new int[radix][arr.length] * 即 10行 arr.length列的规则矩阵,每一行分别是序号为0-9的箱子 * 第一次循环装入个位数字与箱子序号数字对应的元素 * 再从0号箱子开始到9号箱子结束把依次所有元素装进数组中 * 第二次为十位 * 再从0号箱子开始到9号箱子结束把依次所有元素装进数组中 * 以此类推直到数组中最大数的最高位 * @param arr */ public static void radixSort(int[] arr) { int len = arr.length; int radix = 10; int d = getMax(arr);// 最大数的位数 int[][] temp = new int[radix][len];//序号为0-9的箱子 int[] count = new int[radix];//箱子中元素的计数器 for (int m=0,n=1;m<d;m++,n *=radix) {//从个位到最大数的最高位 for (int i = 0; i < len; i++) { int digit = (arr[i] / n % radix);//元素当前位的数值,对应箱子序号 temp[digit][count[digit]++] = arr[i];//把元素放入对应的箱子中 //count[digit]++; //对应序号箱子的计数器加1 } int k=0; //数组下标,依次, for (int i = 0; i < radix; i++) { if (count[i] != 0){ for (int j = 0; j < count[i]; j++) { arr[k] = temp[i][j]; k++; } } count[i] = 0; } } } /** * http://blog.csdn.net/skylinesky/article/details/6612119 * @author skylinesky */ public static void radixSort2(int[] array) { int d = getMax(arr); int radix = 10; int[] temp = new int[arr.length]; int[] count = new int[radix]; int length = array.length; int divide = 1; for (int i = 0; i < d; i++) { System.arraycopy(array, 0,temp, 0, length); Arrays.fill(count, 0); // for (int j = 0; j < array.length; j++) { // temp[j] = arr[j]; // } // for (int j = 0; j < count.length; j++) { // count[j] = 0; // } for (int j = 0; j < length; j++) { int tempKey = (temp[j] / divide) % radix; count[tempKey]++; } for (int j = 1; j < radix; j++) { count[j] = count[j] + count[j - 1]; } // 个人觉的运用计数排序实现计数排序的重点在下面这个方法 for (int j = length - 1; j >= 0; j--) { int tempKey = (temp[j] / divide) % radix; count[tempKey]--; array[count[tempKey]] = temp[j]; } divide = divide * radix; } } private static int getMax(int[] arr) { int max = 0; for (int i : arr) { if (i > max) { max = i; } } return (max+"").length(); } }