数据结构与算法之排序(Java版)
文章目录
- 时间复杂度
- 冒泡排序
- 算法介绍:
- 代码实现:
- 时间性能测试:9s 9355ms
- 选择排序
- 思路解析:
- 代码实现:
- selectSort方法
- Main方法
- 时间性能测试:3s 2650ms
- 插入排序
- 思路解析:
- 核心思想:当前被前值替换,insertIndex--
- insertSort方法
- Main方法调用
- 时间性能测试:1s 539ms
- 希尔排序
- 思路分析:
- 代码实现:
- 交换法
- 一趟排序:
- 多趟排序就需要我们控制步长:
- 步长多趟
- Main方法:
- 时间性能测试: 5s 5457ms
- 移位法:
- 思路分析:
- 代码实现:
- 时间性能分析:1s 20ms 八百万1877ms
- 快速排序
- 思路分析:
- 代码实现:
- quickSort方法
- Main方法
- 出现的问题
- 时间性能测试:1s 37ms 八百万1065ms
- 归并排序
- 思路分析:
- 代码实现:
- 合并方法
- 分离方法(递归)
- Main方法:
- 踩坑:
- 时间性能测试: 1s 17ms 八百万 1097ms
- 基数排序
- 思路分析:
- 代码分析:
- radixSort方法
- Main方法
- 时间性能测试:八百万 600ms
- 八大排序总结:
- 冒泡排序:
- 思路:
- 方法:
- 核心代码:
- 选择排序:
- 思路:
- 方法:
- 核心代码:
- 插入排序:
- 思路:
- 核心代码:
- 快速排序:
- 思路:
- 核心代码:
- 希尔排序:
- 思路:交换法
- 核心代码:
- 思路:移位法
- 核心代码:
- 归并排序:
- 思路:
- 核心代码:
- 基数排序:
- 思路:
- 核心代码:
时间复杂度
冒泡排序
算法介绍:
代码实现:
package sort;import java.util.Arrays;public class BubbleSort {public static void main(String[] args) {int arr[] = {3,9,-1,10,2};int temp =0 ;for (int i = 0; i <arr.length -1 ; i++) {//每一次都要筛掉后面的i响for (int j = 0; j <arr.length -1 -i ; j++) {if (arr[j]>arr[j+1]){temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}System.out.println("第"+(i+1)+"趟排序之后");System.out.println(Arrays.toString(arr));}}
}/*** 三九的梅花红了满山的雪* 萧条枝影* 月牙照人眠* 小伙赶着马车* 手里攥着长鞭* 江风吹过他通红的脸* 锣鼓声声* 正月正* 爆竹声里落尽一地红* 家家户户都点上花灯* 又是一年好收成*//*** 清泠泠的江水留了多久* 像那游子一去不回头* 姑娘含着眼泪站在门口* 一眼望断了多少个秋* 大雪封门,再送财神,野火烧不尽心上的人* 霜花满床就在此良辰* 我俩就订了终身*/
/*** 塞北残阳是他的红装* 一山松柏,做伴娘* 等她的情郎,衣锦还乡* 今生我只与你成双* 锣鼓声声* 正月正* 爆竹声里落尽一地红* 家家户户都点上花灯* 又是一年好收成* 家家户户都点上花灯* 又是一年好收成*/
时间性能测试:9s 9355ms
int[] arr = new int[80000];for (int i = 0; i <80000 ; i++) {arr[i] = (int)(Math.random()*8000000);}Date data1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String format1 = simpleDateFormat.format(data1);System.out.println("排序前的时间为"+format1);bubbleSort(arr);Date data2 = new Date();String format2 = simpleDateFormat.format(data2);System.out.println("排序前的时间为"+format2);//排序前的时间为2021-10-03 10:54:29
//排序后的时间为2021-10-03 10:54:38
选择排序
思路解析:
代码实现:
selectSort方法
public static void selectSort(int[] arr) {//只需要循环arr.length -1 次for (int j = 0; j < arr.length - 1; j++) {//我们姑且当做第一个是最小值,minIndex是最小值的坐标int minIndex = j;int min = arr[j];/*** 然后做一次for循环,和之后的比较一下,* 如果之后有小的,就把min和minIndex都当做那个小的*///在原来的基础上套一层for循环,只需要把后面的arr[0]改为arr[j]就可以了for (int i = j+1; i < arr.length; i++) {if (arr[i] < arr[j]) {//如果小于就让这个最小值当做min,最小值的下标当做minIndexmin = arr[i];minIndex = i;}}//因为当时minIndex被保存下来了,// 所以可以利用minIndex找出当时最小值的坐标arr[minIndex] = arr[j];arr[j] = min;System.out.println("第"+(j+1)+"轮之后");System.out.println(Arrays.toString(arr));}}
Main方法
public static void main(String[] args) {int[] arr = {101, 34, 119, 1};System.out.println("排序之前");System.out.println(Arrays.toString(arr));selectSort(arr);System.out.println("排序之后");System.out.println(Arrays.toString(arr));}
时间性能测试:3s 2650ms
int[] arr = new int[80000];for (int i = 0; i <80000 ; i++) {arr[i] = (int)(Math.random()*8000000);}Date data1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String format1 = simpleDateFormat.format(data1);System.out.println("排序前的时间为"+format1);selectSort(arr);Date data2 = new Date();String format2 = simpleDateFormat.format(data2);System.out.println("排序后的时间为"+format2);
//排序前的时间为2021-10-03 16:52:39
//排序后的时间为2021-10-03 16:52:42
插入排序
思路解析:
核心思想:当前被前值替换,insertIndex–
int insertVal = arr[i]; //对于第一轮我们是想要让第二个数进行排序比较int insertIndex = i - 1; //对于我们想排序的数,我们需要找到当前排序的数的前一个数//insertIndex >=0是为了将数组下标不越界//并且前面的值要小于后面的值while(insertIndex >=0 && arr[insertIndex]>insertVal){//让前面的值替换当前的值,// 当前的值我们已经当做insertVal留下来了//不需要担心值的丢失问题//最后我们会把值替换回来//进行值的替换arr[insertIndex+1] = arr[insertIndex];//然后index--,看前面的值是否小于等于insertVal,如果小于等于那就符合位置了insertIndex--;}
insertSort方法
/*** 插入排序* @param arr*/
public static void insertSort(int[] arr){//下标是从1开始,也就是从第二个开始查找for (int i = 1; i <arr.length ; i++) {int insertVal = arr[i]; //对于第一轮我们是想要让第二个数进行排序比较int insertIndex = i - 1; //对于我们想排序的数,我们需要找到当前排序的数的前一个数//insertIndex >=0是为了将数组下标不越界//并且前面的值要小于后面的值while(insertIndex >=0 && arr[insertIndex]>insertVal){//让前面的值替换当前的值,// 当前的值我们已经当做insertVal留下来了//不需要担心值的丢失问题//最后我们会把值替换回来//进行值的替换arr[insertIndex+1] = arr[insertIndex];//然后index--,看前面的值是否小于等于insertVal,如果小于等于那就符合位置了insertIndex--;}//跳出的时候是insertIndex--;//如果要找到位置的话,需要+1//就比如说insertIndex为-1跳出,但是符合的位置是0arr[insertIndex+1] = insertVal;// System.out.println("第"+i+"轮插入");
// System.out.println(Arrays.toString(arr));}}
Main方法调用
public static void main(String[] args) {// int[] arr = {101,34,119,1,-1,89};int[] arr = new int[80000];for (int i = 0; i <80000 ; i++) {arr[i] = (int)(Math.random()*8000000);}Date data1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String format1 = simpleDateFormat.format(data1);System.out.println("排序前的时间为"+format1);insertSort(arr);Date data2 = new Date();String format2 = simpleDateFormat.format(data2);System.out.println("排序后的时间为"+format2);}
时间性能测试:1s 539ms
排序前的时间为2021-10-03 18:01:17
排序后的时间为2021-10-03 18:01:18
希尔排序
思路分析:
代码实现:
交换法
一趟排序:
//但是这样我们只能推导一趟//逐步推导方式进行希尔排序public static void shellSort(int[] arr){//如果步长为5的话for (int i = 5; i <arr.length ; i++) {/*** /这个设置j是为了分成每组两个* 这个配合i=5使用的*/for (int j = i -5; j >=0 ; j-=5) {if (arr[j]>arr[j+5]){//如果arr[0]>arr[5],第一个大于第六个就交换位置int temp = arr[j];arr[j] = arr[j+5];arr[j+5] = temp;}}}System.out.println("第一趟交换之后");System.out.println(Arrays.toString(arr));}
多趟排序就需要我们控制步长:
步长多趟
/*** 我们采用一个for循环来进行每次的步长的分割*/public static void shellSort(int[] arr) {//步长必须为1,或者比1大的整数int count = 0;for (int foot = arr.length / 2; foot > 0; foot /= 2) {//如果步长为5的话//这个5要换成步长for (int i = foot; i < arr.length; i++) {/*** /这个设置j是为了分成每组两个* 这个配合i=5使用的*/for (int j = i - foot; j >= 0; j -= foot) {if (arr[j] > arr[j + foot]) {//如果arr[0]>arr[5],第一个大于第六个就交换位置int temp = arr[j];arr[j] = arr[j + foot];arr[j + foot] = temp;}}}System.out.println("第" + (++count) + "趟交换之后");System.out.println(Arrays.toString(arr));}}
Main方法:
public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};shellSort(arr);}
时间性能测试: 5s 5457ms
int[] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int) (Math.random() * 8000000);}Long startTime = System.currentTimeMillis();shellSort(arr);Long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);
移位法:
思路分析:
移位法就是看一个数适不适合这个位置,如果不适合继续往前找,直到找到这个位置
代码实现:
/*** 希尔排序->移位法*/public static void shellSort2(int[] arr) {int count = 0;for (int foot = arr.length / 2; foot > 0; foot /= 2) {//从foot个元素开始,逐个对其所在组进行直接插入for (int i = foot; i < arr.length; i++) {int j = i;//将arr[j]保存起来,之后赋值的时候会用到int temp = arr[j];//如果后者小于前者,就把前者往前移//最后空出来的位置肯定是后者的//但是我感觉这个if和后面的while冲突了if (arr[j] < arr[j - foot]) {//如果temp 依然小于j - foot那就一直循环,直到找到合适的位置//就一直往前移,直到合适为止while (j - foot >= 0 && temp < arr[j - foot]) {//让所有大于的数进行提前arr[j] = arr[j-foot];j -= foot;}//找到合适位置就让这个位置的arr[j] = temp;}// System.out.println("第" + (++count) + "趟交换之后");
// System.out.println(Arrays.toString(arr));}
时间性能分析:1s 20ms 八百万1877ms
快速排序
思路分析:
定一个中间值,然后把小于中间值的放在左边,大于中间值的放在右边
代码实现:
quickSort方法
public static void quickSort(int[] arr, int left, int right) {//分三种情况,l<r,l=r,l>rint temp = 0;//将left和right保存起来int l = left;int r = right;int mid = arr[(left + right) / 2];//定一个中间值while (l < r) {while (arr[l] < mid) {l++;}while (arr[r] > mid) {r--;}//如果l>=r就返回if (l >= r) {break;}//这里是不满足上面的条件弹出一个arr[l]一个arr[r]temp = arr[l];arr[l] = arr[r];arr[r] = temp;//忘了这一步,如果发现arr[l]和mid相等if (arr[l]==mid){r--;}if (arr[r]==mid){l++;}}//如果出现l==r的情况了
// 将l优异,r左移if (l == r) {l++;r--;}//最后一种情况就是l>r了//现在这时候的排序情况就是left r l right//然后进行递归if (left < r) {quickSort(arr, left, r);}if (right > l) {quickSort(arr, l, right);}}
Main方法
public static void main(String[] args) {//实现快速排序int[] arr = {-9, 78, 0, 23, -567, 70, -9000, 2311};quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}
出现的问题
没有在交换之后,arr[l],arr[r]和mid有没有相等,有相等的话相对的指针应该后移,否则就会卡壳,少写了这一步
//忘了这一步,如果发现arr[l]和mid相等if (arr[l]==mid){r--;}if (arr[r]==mid){l++;}
时间性能测试:1s 37ms 八百万1065ms
归并排序
思路分析:
分而治之:先拆分成多个,然后合并并排序
采用了分治的思想
代码实现:
合并方法
/*** 合并的方法* @param arr* @param left* @param mid* @param right* @param temp*/public static void merge(int[] arr, int left, int mid, int right, int[] temp) {/*** 1.进行匹配并放在temp数组里面* left是第一位* mid是左边数组的最后一位* right的右边数组的最后一位*/int i = left;int j = mid + 1;int t = 0;//需要注意的是如果这里如果要循环出去的话i一定是>mid或者j一定是>right的while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[t] = arr[i];i+=1;t+=1;}else {//这里要写成else语句temp[t] = arr[j];j+=1;t+=1;}}/*** 2.将剩余的元素全部放在temp数组里面*/while (i <= mid) {temp[t] = arr[i];i+=1;t+=1;}while (j <= right) {temp[t] = arr[j];j+=1;t+=1;}/*** 3.temp里面的元素放在arr里面*///原来是这里把t进行重置了t = 0;int tempLeft = left;//从left到rightwhile (tempLeft <= right) {arr[tempLeft] = temp[t];tempLeft+=1;t+=1;}}
分离方法(递归)
public static void mergeSort(int[] arr, int left, int right, int[] temp) {//这里我写的少一个条件需要left<rightif (left<right){int mid = (left + right) / 2;//向左进行递归mergeSort(arr, left, mid, temp);//向右递归mergeSort(arr, mid + 1, right, temp);//递归分离之后需要合并merge(arr, left, mid, right, temp);}}
Main方法:
public static void main(String[] args) {// int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};
// int[] temp = new int[arr.length];
// mergeSort(arr, 0, arr.length - 1, temp);
// System.out.println("归并后的顺序为" + Arrays.toString(arr));int[] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int) (Math.random() * 8000000);}int[] temp = new int[arr.length];Long startTime = System.currentTimeMillis();mergeSort(arr, 0, arr.length - 1, temp);Long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);}
踩坑:
1.mergeSort方法里面没有if(left<right这个判断条件)
2.temp和arr位置写反
if (arr[i] <= arr[j]) {temp[t] = arr[i];i+=1;t+=1;
}
3.在最后一步将temp放在arr里面没有给t=0赋值
时间性能测试: 1s 17ms 八百万 1097ms
基数排序
思路分析:
代码分析:
radixSort方法
//这个方法是填数值到木桶里面public static void radixSort2(int[] arr) {//定义十个木桶(但是长度不一定)int[][] bucket = new int[10][arr.length];int[] bucketCount = new int[10];//1.假设第一个数就是最大数int max = arr[0];for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}int maxLength = (max +"").length();for (int k = 0,num=1; k <maxLength; k++,num*=10){for (int i = 0; i < arr.length; i++) {//传进来一个数,先判断这个数的个位是几,然后往木桶里面填int ge = arr[i] / num % 10;//这里需要使用个位bucket[ge][bucketCount[ge]] = arr[i];bucketCount[ge]++; //从0开始,如果有就++}//我们放入桶中排好序后,需要重新放入arrint index = 0;//我们需要的是bucket[m][n]for (int m = 0; m < bucketCount.length; m++) {//如果bucketCount[m] ==0 就说明这个容器没有数值在里面if (bucketCount[m] != 0) {//n<buckCount[m] 因为bucketCount[m]是从1开始加的for (int n = 0; n < bucketCount[m]; n++) {//这里放完了需要index++arr[index++] = bucket[m][n];}}//这里要重新将木板清零,为下一次排序做准备bucketCount[m] = 0;}
// System.out.println("第"+(k+1)+"轮,对个位数的处理是arr = " + Arrays.toString(arr));}}
Main方法
public static void main(String[] args) {// int[] arr = {53, 3, 542, 748, 14, 214};
// radixSort2(arr);int[] arr = new int[80000000];for (int i = 0; i < 80000000; i++) {arr[i] = (int) (Math.random() * 800000000);}int[] temp = new int[arr.length];Long startTime = System.currentTimeMillis();radixSort2(arr);Long endTime = System.currentTimeMillis();System.out.println(endTime - startTime);}
时间性能测试:八百万 600ms
八大排序总结:
冒泡排序:
思路:
冒泡排序顾名思义,就是将较大的数像泡泡一样浮上去
方法:
先比较两个数大小,大的排后面,小的排前面
核心代码:
temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;
选择排序:
思路:
选择排序是设置刚开始的一个最小值和最小下标,然后跟以后的值开始比较,如果有值比这个更小就进行值的替换,最后把min和minIndex设置为这个值和这个坐标
方法:
第一个for循环负责遍历数字里面的所有值,第二个for循环负责遍历该值以后的所有值,如果有小的就进行替换值
核心代码:
for (int j = 0; j < arr.length - 1; j++) {//我们姑且当做第一个是最小值,minIndex是最小值的坐标int minIndex = j;int min = arr[j];/*** 然后做一次for循环,和之后的比较一下,* 如果之后有小的,就把min和minIndex都当做那个小的*///在原来的基础上套一层for循环,只需要把后面的arr[0]改为arr[j]就可以了for (int i = j + 1; i < arr.length; i++) {if (arr[i] < arr[j]) {min = arr[i];minIndex = i;}}//因为当时minIndex被保存下来了,// 所以可以利用minIndex找出当时最小值的坐标arr[minIndex] = arr[j];arr[j] = min;
// System.out.println("第"+(j+1)+"轮之后");
// System.out.println(Arrays.toString(arr));}
插入排序:
思路:
将这个和前面的比较,如果当前值比前面的小的话,把当前值存起来,让前面的值放在当前的位置,然后继续找前面的前面的值,如果前面的前面还是大的话那么就继续替换,直到找到合适位置
核心代码:
for (int i = 1; i < arr.length; i++) {int insertVal = arr[i]; //对于第一轮我们是想要让第二个数进行排序比较int insertIndex = i - 1; //对于我们想排序的数,我们需要找到当前排序的数的前一个数//insertIndex >=0是为了将数组下标不越界//并且前面的值要小于后面的值while (insertIndex >= 0 && arr[insertIndex] > insertVal) {//让前面的值替换当前的值,// 当前的值我们已经当做insertVal留下来了//不需要担心值的丢失问题//最后我们会把值替换回来//进行值的替换arr[insertIndex + 1] = arr[insertIndex];//然后index--,看前面的值是否小于等于insertVal,如果小于等于那就符合位置了insertIndex--;}//跳出的时候是insertIndex--;//如果要找到位置的话,需要+1//就比如说insertIndex为-1跳出,但是符合的位置是0// if (insertIndex + 1 != i) {// arr[insertIndex + 1] = insertVal;
// }arr[insertIndex + 1] = insertVal;// System.out.println("第"+i+"轮插入");
// System.out.println(Arrays.toString(arr));}
快速排序:
思路:
定义一个中间值,分三种情况
1.当l<r的时候,如果左边小于中间值,右边大于中间值,l++,r–,否则弹出一个左边大的一个右边小的,然后进行交换,不排除特殊情况,如果左边的=中间,右边的=中间则l++,r–
2.当l==r,则l++,r–
3.当l>r的时候,说明这个遍历完了,应该继续设置中间值递归其他两块了
if (left < r) {quickSort2(arr, left, r);}if (right > l) {quickSort2(arr, l, right);}
核心代码:
public static void quickSort2(int[] arr, int left, int right) {//分三种情况,l<r,l=r,l>rint temp = 0;//将left和right保存起来int l = left;int r = right;int mid = arr[(left + right) / 2];//定一个中间值while (l < r) {while (arr[l] < mid) {l++;}while (arr[r] > mid) {r--;}//如果l>=r就返回if (l >= r) {break;}//这里是不满足上面的条件弹出一个arr[l]一个arr[r]temp = arr[l];arr[l] = arr[r];arr[r] = temp;//忘了这一步,如果发现arr[l]和mid相等if (arr[l]==mid){r--;}if (arr[r]==mid){l++;}}//如果出现l==r的情况了
// 将l优异,r左移if (l == r) {l++;r--;}//最后一种情况就是l>r了//现在这时候的排序情况就是left r l right//然后进行递归if (left < r) {quickSort2(arr, left, r);}if (right > l) {quickSort2(arr, l, right);}
希尔排序:
思路:交换法
设置步长为长度/2组,第一次利用双for循环将组分为2组,步长为length/2
第二次分为4组,就这样依次排序依次分如果该组前面的数组大于后面的数据就交换
核心代码:
for (int foot = arr.length / 2; foot > 0; foot /= 2) {//如果步长为5的话//这个5要换成步长for (int i = foot; i < arr.length; i++) {/*** /这个设置j是为了分成每组两个* 这个配合i=5使用的*/for (int j = i - foot; j >= 0; j -= foot) {if (arr[j] > arr[j + foot]) {//如果arr[0]>arr[5],第一个大于第六个就交换位置int temp = arr[j];arr[j] = arr[j + foot];arr[j + foot] = temp;//无 break 5604; 5528//有break 13 11break;}}}
// System.out.println("第" + (++count) + "趟交换之后");
// System.out.println(Arrays.toString(arr));}
思路:移位法
分完组之后,如果当前的值小于之前的值,就保存当前值,让之前的值替换当前值,如果还小于之前的之前的值就继续替换
核心代码:
public static void shellSort2(int[] arr) {int count = 0;for (int foot = arr.length / 2; foot > 0; foot /= 2) {//从foot个元素开始,逐个对其所在组进行直接插入for (int i = foot; i < arr.length; i++) {int j = i;//将arr[j]保存起来,之后赋值的时候会用到int temp = arr[j];//如果后者小于前者,就把前者往前移//最后空出来的位置肯定是后者的//但是我感觉这个if和后面的while冲突了if (arr[j] < arr[j - foot]) {//如果temp 依然小于j - foot那就一直循环,直到找到合适的位置//就一直往前移,直到合适为止while (j - foot >= 0 && temp < arr[j - foot]) {//让所有大于的数进行提前arr[j] = arr[j-foot];j -= foot;}//找到合适位置就让这个位置的arr[j] = temp;}// System.out.println("第" + (++count) + "趟交换之后");
// System.out.println(Arrays.toString(arr));}}
归并排序:
思路:
定义,left,mid,right,然后比较[left,mid]和[mid+1,right]哪个小就让哪个排前面,分离的时候需要递归分离
核心代码:
public static void mergeSort(int[] arr, int left, int right, int[] temp) {//这里我写的少一个条件需要left<rightif (left<right){int mid = (left + right) / 2;//向左进行递归mergeSort(arr, left, mid, temp);//向右递归mergeSort(arr, mid + 1, right, temp);//递归分离之后需要合并merge(arr, left, mid, right, temp);}}/*** 合并的方法** @param arr* @param left* @param mid* @param right* @param temp*/public static void merge(int[] arr, int left, int mid, int right, int[] temp) {/*** 1.进行匹配并放在temp数组里面* left是第一位* mid是左边数组的最后一位* right的右边数组的最后一位*/int i = left;int j = mid + 1;int t = 0;//需要注意的是如果这里如果要循环出去的话i一定是>mid或者j一定是>right的while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[t] = arr[i];i+=1;t+=1;}else {//这里要写成else语句temp[t] = arr[j];j+=1;t+=1;}}/*** 2.将剩余的元素全部放在temp数组里面*/while (i <= mid) {temp[t] = arr[i];i+=1;t+=1;}while (j <= right) {temp[t] = arr[j];j+=1;t+=1;}/*** 3.temp里面的元素放在arr里面*///原来是这里把t进行重置了t = 0;int tempLeft = left;//从left到rightwhile (tempLeft <= right) {arr[tempLeft] = temp[t];tempLeft+=1;t+=1;}}
基数排序:
思路:
设计十个木桶,对于他们每一位都进行排序,排序好之后将排序号的重新填入数组
核心代码:
public static void radixSort2(int[] arr) {//定义十个木桶(但是长度不一定)int[][] bucket = new int[10][arr.length];int[] bucketCount = new int[10];//1.假设第一个数就是最大数int max = arr[0];for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}int maxLength = (max +"").length();for (int k = 0,num=1; k <maxLength; k++,num*=10){for (int i = 0; i < arr.length; i++) {//传进来一个数,先判断这个数的个位是几,然后往木桶里面填int ge = arr[i] / num % 10;//这里需要使用个位bucket[ge][bucketCount[ge]] = arr[i];bucketCount[ge]++; //从0开始,如果有就++}//我们放入桶中排好序后,需要重新放入arrint index = 0;//我们需要的是bucket[m][n]for (int m = 0; m < bucketCount.length; m++) {//如果bucketCount[m] ==0 就说明这个容器没有数值在里面if (bucketCount[m] != 0) {//n<buckCount[m] 因为bucketCount[m]是从1开始加的for (int n = 0; n < bucketCount[m]; n++) {//这里放完了需要index++arr[index++] = bucket[m][n];}}//这里要重新将木板清零,为下一次排序做准备bucketCount[m] = 0;}
// System.out.println("第"+(k+1)+"轮,对个位数的处理是arr = " + Arrays.toString(arr));}}
数据结构与算法之排序(Java版)相关推荐
- 数据结构与算法基础(java版)
目录 数据结构与算法基础(java版) 1.1数据结构概述 1.2算法概述 2.1数组的基本使用 2.2 数组元素的添加 2.3数组元素的删除 2.4面向对象的数组 2.5查找算法之线性查找 2.6查 ...
- 数据结构与算法之链表(Java版)
文章目录 链表 单链表完成添加的遍历 按照顺序添加英雄 解题思路: 代码实现: 单链表的修改 解题思路: 代码实现: 单链表的删除: 解题思路: 代码实现: 实战演练 找出单链表中有效节点的个数 查找 ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- 在Object-C中学习数据结构与算法之排序算法
笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速 ...
- 数据结构与算法(三) 排序算法(代码示例)
数据结构与算法三 排序算法 1. 选择排序 2. 插入排序 3. 冒泡排序 4. 归并排序 5. 快速排序 6. 希尔排序 7. 堆排序 总结 1. 选择排序 选择排序的基本原理: 对于未排序的一组记 ...
- 数据结构与算法之排序算法
数据结构与算法之排序算法 排序算法的介绍 排序也称排序算法(Sort Algorithm),排序是将一组数据,依指定的顺序进行排序的过程. 排序的分类 1)内部排序:指将需要处理的数据都加载到内部 ...
- 数据结构排序算法实验报告_[数据结构与算法系列]排序算法(二)
我的上一篇文章向大家介绍了排序算法中的冒泡排序.插入排序和选择排序.它们都是平均时间复杂度为 O(n^2) 的排序算法,同时还为大家讲解了什么是原地排序和什么是排序的稳定性.下图是这三种算法的比较,不 ...
- 数据结构与算法(陈越版)第五讲 (树下)树的应用——集合及其运算
数据结构与算法(陈越版)第五讲 (树下)树的应用--集合及其运算 一.集合的表示 1.1.集合的表示 1.2.集合的储存 二.集合的运算 2.1查找以及普通并 2.2按照秩的合并算法 2.3路径压缩优 ...
- java动态分区分配_操作系统 动态分区分配算法课程设计 java版.pdf
操作系统 动态分区分配算法课程设计 java版 湖 南 文 理 学 院 实 验 报 告 课程名称 操作系统课程设计 实验名称 存储管理--动态分区分配算法的模拟 成绩 学生姓名 曹乐 专业 计算机 班 ...
- 算法练习5---快速排序Java版
基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成 ...
最新文章
- iOS网络编程-iCloud键值数据存储编程实例
- HQL查询(分页查询,动态sql查询,参数查询)
- 每日一皮:程序员和黑客的区别
- 互联网1分钟 | 0110 腾讯联手拳头游戏成立腾竞体育;百度智能云发布中国首款智能边缘计算产品BIE...
- 通用权限管理系统组件 (GPM - General Permissions Manager) 中及时通讯功能的改进
- jdbctemplate mysql 配置_Spring JDBCTemplate配置使用
- eclipse类自动生成注释
- java 扫描类_Java扫描指定包中所有类
- MATLAB实现BP神经网络预测汽油辛烷值
- 第二十三:Appium+Pytest实现app并发测试
- 预防SQL注入攻击之我见 转
- Atitit 二进制数据字节转字符串 base64 base16 Quoted-printable BINHEX
- 【rose】rose框架学习总结
- CAD软件中沿墙镜像功能的使用技巧
- [Mac/Windows] Affinity Photo | 正品序列号 | 专业的图片编辑工具
- Altera的IP核
- Java中随机数的产生方法
- 参加华为认证HCIP-AI的经历
- 目标跟踪算法 - CMT、TLD、KCF现成代码编译
- 如何用好百度搜索风云榜?