常见排序算法及java实现

小咪咪 2022-12-11 12:27 284阅读 0赞

在这里插入图片描述

排序算法时间复杂度和空间复杂度

在这里插入图片描述

1. 冒泡排序

基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。

过程

比较相邻的两个数据,如果第一个数比第二个数小,就交换位置。一直比较到最后两个数据。最终最小数被交换到n的位置,这样第一个最小数的位置就排好了。
继续重复上述过程,依次将第2.3…n-1个最小数排好位置。
java实现

  1. public static void BubbleSort(int[] arr){
  2. for(int i = 0;i<arr.length-1;i++){
  3. for(int j = 0;j<arr.length-1-i ; j++){
  4. if(arr[j]<arr[j+1])
  5. {
  6. int temp = arr[j];
  7. arr[j] = arr[j+1];
  8. arr[j+1] = temp;
  9. }
  10. }
  11. }
  12. }

2.快速排序算法

基本思想:分治法,①一边大一边小,取第一个数字作为标准,比它大的放右边,小的放左边;②分别迭代标准值的左边数组和右边数组

  1. //快速排序,分治,一边大一边小,取第一个数字作为标准,比它大的放右边,小的放左边
  2. //分别迭代标准值的左边和右边
  3. public static void quickSort(int[] arr, int start, int end){
  4. if(start<end){
  5. //把数组中第0个数字作为标准数
  6. int stand = arr[start];
  7. //记录需要排序的下标
  8. int low = start;
  9. int high = end;
  10. //循环找出比标准数大的数和比标准数小的数
  11. while(low<high){
  12. //右边数字比标准数大
  13. while(low<high && arr[high]>= stand){
  14. high--;
  15. }
  16. //右边数字替换左边数字
  17. arr[low]=arr[high];
  18. //左边数字比标准数小
  19. while (low<high && arr[low]<=stand){
  20. low++;
  21. }
  22. //左边数字替换右边数字
  23. arr[high]=arr[low];
  24. }
  25. //把标准数赋给低位所在位置的元素
  26. arr[low] = stand;
  27. //处理所有的小的数字
  28. quickSort(arr,start,low);
  29. //处理所有的大的数字
  30. quickSort(arr,low+1,end);
  31. }
  32. }

3.插入排序算法

基本思想:从1位开始逐次与前面的值比较,如果该值比前面的值小,则把大值后移,并把1位值放到不大于的位置,遍历完后,从2位开始逐次与前面比。
过程:在区间 [1,length-1] ,从1位开始作为指针,for循环操作;指针位 j =i-1 (j在0~j之间)与 i 位进行比较,如果 i 比 j 位的值小,则 j 位值赋值给 j+1 位,若不小,则 j+1位值为 i位值。

  1. //插入排序
  2. public static void insertSort(int[] arr){
  3. //遍历所有数字
  4. for (int i = 1; i < arr.length; i++) {
  5. //如果当前数字比前一个小
  6. if(arr[i]<arr[i-1]){
  7. //把当前遍历数字存起来
  8. int temp = arr[i];
  9. int j;
  10. //遍历当前数字前面所有数字
  11. for(j=i-1;j>=0 && arr[j]>temp;j--){
  12. //把前一个数字赋给后一个数字
  13. arr[j+1] = arr[j];
  14. }
  15. //把临时变量赋给不满足条件的后一个元素
  16. arr[j+1] = temp;
  17. }
  18. }
  19. }

4.希尔排序算法

基本思想:(类比插入排序算法,解决了插入排序中小数在末尾导致最终移动次数过多的情况,提升效率。)每次比较步长间隔的数组。

过程:设定步长为d=length/2,循环一次后,步长d = d/2,直到d/2为0。在每次循环步长的数组中,采用插入排序算法。

  1. //希尔排序算法
  2. public static void shellSort(int[] arr){
  3. //遍历所有步长
  4. for (int d = arr.length/2; d > 0; d/=2) {
  5. //遍历元素
  6. for (int i = d; i < arr.length; i+=d) {
  7. //如果当前元素小于减步长后的那个元素,循环交换位置
  8. if(arr[i]<arr[i-d]){
  9. for (int j = i-d; j >=0; j-=d) {
  10. //如果当前元素大于加上步长后的那个元素
  11. if(arr[j]>arr[j+d]){
  12. int temp = arr[j];
  13. arr[j] = arr[j + d];
  14. arr[j + d] = temp;
  15. }
  16. }
  17. }
  18. }
  19. }
  20. }

5.选择排序算法

基本思想:遍历数组,每次都找数组中最小的元素,进行交换。
过程:遍历所有数;如果最小数下标和当前遍历数的下标不一致,说明下标为minIndex的数比当前遍历的数小,交换位置;再判断,次小数下标和当前遍历数的下标不一致,再交换位置;直到遍历完数组。
在这里插入图片描述

  1. //选择排序
  2. public static void selectSort(int[] arr){
  3. //遍历所有数
  4. for (int i = 0; i < arr.length; i++) {
  5. int minIndex = i;
  6. //把当前遍历的数和后面所有的数依次比较,并记录最小数的下标
  7. for (int j = i+1; j < arr.length; j++) {
  8. if(arr[j]<arr[minIndex]){
  9. minIndex = j;
  10. }
  11. }
  12. //如果最小数下标和当前遍历数的下标不一致,说明下标为minIndex的数比当前遍历的数小,交换位置
  13. if(minIndex!=i){
  14. int temp = arr[minIndex];
  15. arr[minIndex] = arr[i];
  16. arr[i] = temp;
  17. }
  18. }
  19. }

6.归并排序算法

基本思想:两个有序数组,逐位比较,小的放到新数组里。

过程:Merge方法处理两个有序数组,用一个临时数组temp存放排序后的数组;MergeSort方法负责把无序数组切分成两个数组,之后归并排序。

  1. //归并排序
  2. public static void MergeSort(int[] arr,int low, int high){
  3. if(low<high){
  4. int middle = (high+low)/2;
  5. //处理左边
  6. MergeSort(arr,low,middle);
  7. //处理右边
  8. MergeSort(arr,middle+1,high);
  9. //归并
  10. Merge(arr,low,middle,high);
  11. }
  12. }
  13. public static void Merge(int[] arr,int low, int middle, int high){
  14. //用于归并后的临时数组
  15. int[] temp = new int[high-low+1];
  16. //记录第一个数组中需要遍历的下标
  17. int i = low;
  18. //记录第二个数组中需要遍历的下标
  19. int j = middle+1;
  20. //记录临时数组存放的下标
  21. int index = 0;
  22. //遍历两个数组,取出较小的数组,放入临时数组
  23. while(i<=middle && j<=high){
  24. //若第一个数组中的值较小
  25. if(arr[i]<arr[j]){
  26. //小数据放入临时数组
  27. temp[index] = arr[i];
  28. i++;
  29. }else{
  30. temp[index] = arr[j];
  31. j++;
  32. }
  33. index++;
  34. }
  35. //处理多余数据
  36. while(i<=middle){
  37. temp[index]=arr[i];
  38. i++;
  39. index++;
  40. }
  41. while(j<=high){
  42. temp[index]=arr[j];
  43. j++;
  44. index++;
  45. }
  46. //临时数组中的数据存入原数组
  47. for (int k = 0; k < temp.length; k++) {
  48. arr[low+k] = temp[k];
  49. }
  50. }

7.基数排序

适用于大数小数都有,位数相差明显,eg:{2,53,1,684,222,64,33}
基本思想:第一轮:首先把数字按个位放到相对数字的桶里(共10个桶,0~9),然后从前往后的顺序从桶里取出元素,每个桶里的元素按照先放的先取的顺序;第二轮:把数字按十位放到相对数字的桶里,再同样的方式取出;第三轮:按百位取。。。轮数看数组中最大的数字有几位则比较几轮。
在这里插入图片描述

  1. //基数排序
  2. public static void radixSort(int[] arr){
  3. //存数组中最大的元素
  4. int max=Integer.MIN_VALUE;
  5. for (int i = 0; i < arr.length; i++) {
  6. if(arr[i]>max){
  7. max=arr[i];
  8. }
  9. }
  10. //计算最大数字是几位数
  11. int maxLength = (max+"").length();
  12. //用于临时存储数据的数组
  13. int[][] temp = new int[10][arr.length];
  14. //用于记录在temp中相应的数组中存放的数组的数量
  15. int[] counts = new int[10];
  16. //根据最大长度的数决定比较的次数
  17. for (int i = 0,n=1; i < maxLength; i++,n*=10) {
  18. //每个数分别计算余数
  19. for (int j = 0; j < arr.length; j++) {
  20. //计算余数
  21. int ys = arr[j]/n%10;
  22. //把当前遍历的数据放入指定的数组中
  23. temp[ys][counts[ys]] = arr[j];
  24. //记录数量
  25. counts[ys]++;
  26. }
  27. //记录取的元素需要放的位置
  28. int index = 0;
  29. //取出数字
  30. for (int k = 0; k < counts.length; k++) {
  31. //记录数量的数组counts中,当前余数记录的数量不为0
  32. if(counts[k]!=0){
  33. //循环取出元素
  34. for (int l = 0; l < counts[k]; l++) {
  35. arr[index] = temp[k][l];
  36. index++;
  37. }
  38. //把数量置为0
  39. counts[k]=0;
  40. }
  41. }
  42. }
  43. }

8.堆排序

基本思想
完全二叉树,父节点内容大于子节点内容

发表评论

表情:
评论列表 (有 0 条评论,284人围观)

还没有评论,来说两句吧...

相关阅读

    相关 常见排序算法Java实现

    想起来去年的现在正在学习数据结构,时间好快哦。今天在微博加到一个漂亮女孩在的微信,她说看我评论比较搞笑,是我太沙雕了吗,不,不是的,我只是一个又皮又欠揍的可爱男孩子。 ...

    相关 排序算法java实现

    一、简介 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 二、排序

    相关 排序算法】堆排序原理Java实现

    1、基本思想 堆是一种特殊的树形数据结构,其每个节点都有一个值,通常提到的堆都是指一颗完全二叉树,根结点的值小于(或大于)两个子节点的值,同时,根节点的两个子树也分别是一

    相关 Java实现常见排序算法

    排序的基本概念与分类 排序是我们生活中经常会面对的问题。同学们做操时会按照从矮到高排列;老师查看上课出勤情况时,会按学生学号顺序点名;高考录取时,会按成绩总分降序依