文章目录
- 1.总览
- 1.待操作数组
- 2.直接插入排序(O(n2))
- 3.希尔排序
- 4.直接选择排序
- 5.堆排序
- 5.1.堆的分类
- 5.2.原理:
- 5.3. 堆排序方法:
- 6.冒泡排序
- 7.快速排序
- 8.归并排序
- 9.基数排序
1.总览
1.待操作数组
private static int[] ori = {30, 70, 40, 60, 10, 90, 20, 50, 80, 100};
2.直接插入排序(O(n2))
原理:当插入第i个元素时,R1,R2 … Ri-1已经基本有序,将i元素和R1,R2 … Ri-1比较,插入合适的位置。
实现一(原理直译成代码,用两个数组,将原数组元素逐个插入新数组):
public static int[] straightInsertionSort(int[] ori) {//初始化sortint [] sort = new int[ori.length];//逐个将ori元素插入sortfor (int i = 0; i < ori.length; i++) {int ele = ori[i];if(i == 0){//sort 为空,ele 放入第一位置sort[0] = ele;}else {//sort 不为空,ele 与 sort 逐个比较for (int j = 0; j < sort.length; j++) {if(ele<sort[j]){//ele 小于 当前sort,ele 放入当前位置,sort 其余值后移for (int k = sort.length-1 ; k>j ; k--){sort[k] = sort[k-1];}sort[j] =ele;break;}else if(0==sort[j+1]){ //由于int数组初始化后,每一位默认值都是0,如果下一位为0,当前位就是最后一位//ele 比sort最后一个元素大,放入最后一个位置sort[j+1] =ele;break;}else {//比当前sort大,且当前sort不是最后一个值,就和下一个sort比较continue;}}}}return sort;}
3.希尔排序
原理:R1,R2 … Ri-1,取一个小于i的整数d1作为第一个增量,将所有距离间隔d1的元素放到一组(头和尾,不包括中间),组内直接选择排序;然后取第二个增量d2<d1重复分组和排序,直至dt=1;
4.直接选择排序
原理:R1,R2 … Ri-1,将最小的元素与第1个位置元素交换;在剩余其他元素中选出最小的元素与第2个位置交换;…直至整体都排列好。
public static int[] straightSelectSort(int[] ori) {int minIndex = 0;//最小数值角标int temp = 0;//交换临时空间for (int i = 0; i < ori.length; i++) {minIndex = i;//最小数值角标初始化为当前i//当前剩余未排序的数组中 选出最小的元素的角标for (int j = i + 1; j < ori.length; j++) {if (ori[minIndex] > ori[j]) {minIndex = j;}}//将最小位置与当前第i位交换temp = ori[i];ori[i] = ori[minIndex];ori[minIndex] = temp;}return ori;}
5.堆排序
5.1.堆的分类
大顶堆:所有父节点都比子节点大;用于从大到小排列;
小顶堆:所有父节点都比子节点小;用于从小到大排列;
5.2.原理:
R1,R2 … Ri-1,将所有元素构建成小顶堆,取出根节点即为最小值。重新调整堆结构,再取出根节点即为次小值…堆排序适合取出前n个值。
5.3. 堆排序方法:
小顶堆的构造方法:先将所有值最为节点构成完全二叉树,从最后一个节点到根节点,根据小顶堆的调整方法调整;
小顶堆的排序方法:取出根节点后,把完全二叉树的最后一个节点放到根节点的位置,从根节点开始,根据小顶堆的调整方法调整;
小顶堆的调整方法:检查当前左右子节点是否都比根节点大,不满足,则交换最小子节点与父节点的位置。如果调整后子节点不为叶子节点,则递归调整以该叶子节点为根节点的树;
在这里插入代码片
6.冒泡排序
原理:相邻的元素进行比较和交换,将排序码小的元素逐渐从底部移到顶部;整个过程就像是水底的气泡逐渐上冒;
public static void bubbleSort(int[] ori){int temp = 0;//外层循环,每次循环都选出一个最大得放置在数组最后for (int i = 0; i < ori.length-1; i++) {//内层循环,数组末尾放置好的元素不在动for (int j = 0; j < ori.length-1-i; j++) {if (ori[j] > ori[j+1]) {//相邻两个数比较,大的右移temp = ori[j];ori[j] = ori[j+1];ori[j+1] =temp;}}}}
7.快速排序
原理:
分治法(将原问题分解成若干规模更小单结构和原问题相似的子问题,通过递归的解决子问题,将子问题的解组合成原问题的解)
第一步:待排序数组中 ,取一个数作为基准,将所有记录分成两组,第1组都小于基准,第2组都大于基准;
第二布:采用相同的方法对左右两组进行排序,直到所有记录排到相应的位置;
/** @Description: 快速排序* @param arr: 待排序数组* @param begin: 开始元素角标* @param end: 末尾元素角标* @return void* @see*/private static void quickSort(int[] arr, int begin, int end) {if(begin<end){int index = patition(arr,begin,end);//基准角标(index左侧元素都比arr[index]小,index右侧元素都比arr[index]大)quickSort(arr,begin,index-1);//递归对分区的左侧快速排序quickSort(arr,index+1,end);//递归对分区的右侧快速排序}}/** @Description: 以最后一个元素最为元素基准,将数组分册两个区域* @param arr: 带分区数组* @param begin: 开始元素角标* @param end: 末尾元素角标* @return int 基准角标* @see*/private static int patition(int[] arr, int begin, int end) {int index = begin-1;//基准 初始角标int patition = arr[end];//基准数值 取最后一个元素的值for (int i = begin; i <= end-1; i++) {if(arr[i]<=patition){//当前值比基准值小index++;//index角标右移一位swap(arr,i,index);//把当前元素和index元素的数值交换}}//index角标右移一位的角标,就是第一个比基准数值大的元素,交换两者位置,就实现了快速排序的分区swap(arr,++index,end);return index;}/** @Description: 交换数组两个元素的数值*/private static void swap(int[] arr, int x, int y) {int temp = arr[x];arr[x] = arr[y];arr[y] = temp;}
8.归并排序
原理:先将整个待排序数组分成若干子表;完成子表内的排序;将两个或两个以上的有序子表合并成一个新的有序表(合并过程:比较A[i]和B[j]的排序码,将较小的元素复制到R[k]中,并令i(或j)和k分别加1,如此循环下去,知道A或B比较复制完,将另一个有序表剩余元素复制到R中);
9.基数排序
原理:适用于元素很多,但是关键字很少的序列;例如,多个百以内的数字排序,关键字只有三个,个位,十位,百位。