首页 > 编程语言 >各种排序算法实现(JAVA)

各种排序算法实现(JAVA)

时间:2022-10-26 14:58:51浏览次数:82  
标签:arr JAVA temp int length ++ 算法 排序 public

转载: https://blog.csdn.net/qq_42453117/article/details/100036347

Exer010Sort01BubbleSortV1

 

 

 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 冒泡排序
  * 它重复地访问过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来
  */
 public class Exer010Sort01BubbleSortV1 {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         //记录比较次数
         int count = 0;
         //i=0,第一轮比较
         for (int i = 0; i < a.length - 1; i++) {
             //第一轮,两两比较
             for (int j = 0; j < a.length - 1 - i; j++) {
                 if (a[j] > a[j + 1]) {
                     int temp = a[j];
                     a[j] = a[j + 1];
                     a[j + 1] = temp;
                }
                 count++;
            }
        }
         System.out.println(Arrays.toString(a));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
         System.out.println("一共比较了:" + count + "次");//一共比较了:105次
    }
 }
 ​

Exer010Sort01BubbleSortV2

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 优化,减少排序次数
  */
 public class Exer010Sort01BubbleSortV2 {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         int count = 0;
         for (int i = 0; i < a.length - 1; i++) {
             boolean flag = true;
             for (int j = 0; j < a.length - 1 - i; j++) {
                 if (a[j] > a[j + 1]) {
                     int temp = a[j];
                     a[j] = a[j + 1];
                     a[j + 1] = temp;
                     flag = false;
                }
                 count++;
            }
             if (flag) {
                 break;
            }
        }
         System.out.println(Arrays.toString(a));// [2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
         System.out.println("一共比较了:" + count + "次");//一共比较了:95次
    }
 }
 ​
 ​

Exer010Sort02SelectSort

 

 

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 选择排序
  * 先定义一个记录最小元素的下标,然后循环一次后面的,找到最小的元素,最后将他放到前面排序好的序列。
  */
 public class Exer010Sort02SelectSort {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         for (int i = 0; i < a.length - 1; i++) {
             int index = i;//标记第一个为待比较的数
             for (int j = i + 1; j < a.length; j++) { //然后从后面遍历与第一个数比较
                 if (a[j] < a[index]) {  //如果小,就交换最小值
                     index = j;//保存最小元素的下标
                }
            }
             //找到最小值后,将最小的值放到第一的位置,进行下一遍循环
             int temp = a[index];
             a[index] = a[i];
             a[i] = temp;
        }
         System.out.println(Arrays.toString(a));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    }
 ​
 }
 ​

Exer010Sort03InsertSort

 

 

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 插入排序
  * 定义一个待插入的数,再定义一个待插入数的前一个数的下标,然后拿待插入数与前面的数组一一比较,最后交换。
  */
 public class Exer010Sort03InsertSort {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         for (int i = 0; i < a.length; i++) {  //长度不减1,是因为要留多一个位置方便插入数
             //定义待插入的数
             int insertValue = a[i];
             //找到待插入数的前一个数的下标
             int insertIndex = i - 1;
             while (insertIndex >= 0 && insertValue < a[insertIndex]) {//拿a[i]与a[i-1]的前面数组比较
                 a[insertIndex + 1] = a[insertIndex];
                 insertIndex--;
            }
             a[insertIndex + 1] = insertValue;
        }
         System.out.println(Arrays.toString(a));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    }
 }
 ​

Exer010Sort04ShellSort

 

 

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 希尔排序
  * 插入排序的升级
  */
 public class Exer010Sort04ShellSort {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         int count = 0;//比较次数
         for (int gap = a.length / 2; gap > 0; gap = gap / 2) {
             //将整个数组分为若干个子数组
             for (int i = gap; i < a.length; i++) {
                 //遍历各组的元素
                 for (int j = i - gap; j >= 0; j = j - gap) {
                     //交换元素
                     if (a[j] > a[j + gap]) {
                         int temp = a[j];
                         a[j] = a[j + gap];
                         a[j + gap] = temp;
                         count++;
                    }
                }
            }
        }
         System.out.println(count);//16
         System.out.println(Arrays.toString(a));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]
    }
 ​
 }
 ​

Exer010Sort05QuickSort

 

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  *   快速排序
  */
 public class Exer010Sort05QuickSort {
     public static void main(String[] args) {
         //int a[]={50,1,12,2};
         int a[]={3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
         quicksort(a,0,a.length-1);
         System.out.println(Arrays.toString(a));
    }
     private static void quicksort(int[] a, int low, int high) {
         int i,j;
         if (low>high) {
             return;
        }
         i=low;
         j=high;
         int temp=a[low];//基准位,low=length时,会报异常,java.lang.ArrayIndexOutOfBoundsException: 4 ,所以必须在if判断后面,就跳出方法。
         while(i<j){
             //先从右边开始往左递减,找到比temp小的值才停止
             while ( temp<=a[j] && i<j) {
                 j--;
            }
             //再看左边开始往右递增,找到比temp大的值才停止
             while ( temp>=a[i] && i<j) {
                 i++;
            }
             //满足 i<j 就交换,继续循环while(i<j)
             if (i<j) {
                 int t=a[i];
                 a[i]=a[j];
                 a[j]=t;
            }
        }
         //最后将基准位跟 a[i]与a[j]相等的位置,进行交换,此时i=j
         a[low]=a[i];
         a[i]=temp;
         //左递归
         quicksort(a, low, j-1);
         //右递归
         quicksort(a, j+1, high);
    }
 ​
 }
 ​

Exer010Sort06MergeSort

 

 

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 合并排序
  */
 public class Exer010Sort06MergeSort {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         //int a[]={5,2,4,7,1,3,2,2};
         int temp[] = new int[a.length];
         mergesort(a, 0, a.length - 1, temp);
         System.out.println(Arrays.toString(a));
    }
 ​
     private static void mergesort(int[] a, int left, int right, int[] temp) {
         //分解
         if (left < right) {
             int mid = (left + right) / 2;
             //向左递归进行分解
             mergesort(a, left, mid, temp);
             //向右递归进行分解
             mergesort(a, mid + 1, right, temp);
             //每分解一次便合并一次
             merge(a, left, right, mid, temp);
        }
 ​
    }
 ​
     private static void merge(int[] a, int left, int right, int mid, int[] temp) {
         int i = left; //初始i,左边有序序列的初始索引
         int j = mid + 1;//初始化j,右边有序序列的初始索引(右边有序序列的初始位置即中间位置的后一位置)
         int t = 0;//指向temp数组的当前索引,初始为0
 ​
         //先把左右两边的数据(已经有序)按规则填充到temp数组
         //直到左右两边的有序序列,有一边处理完成为止
         while (i <= mid && j <= right) {
             //如果左边有序序列的当前元素小于或等于右边的有序序列的当前元素,就将左边的元素填充到temp数组中
             if (a[i] <= a[j]) {
                 temp[t] = a[i];
                 t++;//索引向后移
                 i++;//i后移
            } else {
                 //反之,将右边有序序列的当前元素填充到temp数组中
                 temp[t] = a[j];
                 t++;//索引向后移
                 j++;//j后移
            }
        }
         //把剩余数据的一边的元素填充到temp中
         while (i <= mid) {
             //此时说明左边序列还有剩余元素
             //全部填充到temp数组
             temp[t] = a[i];
             t++;
             i++;
        }
         while (j <= right) {
             //此时说明左边序列还有剩余元素
             //全部填充到temp数组
             temp[t] = a[j];
             t++;
             j++;
        }
         //将temp数组的元素复制到原数组
         t = 0;
         int tempLeft = left;
         while (tempLeft <= right) {
             a[tempLeft] = temp[t];
             t++;
             tempLeft++;
        }
    }
 ​
 ​
 }
 ​

Exer010Sort07HeapSort

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 堆排序
  */
 public class Exer010Sort07HeapSort {
     public static void main(String[] args) {
         int a[] = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
         sort(a);
         System.out.println(Arrays.toString(a));
    }
 ​
     public static void sort(int[] arr) {
         int length = arr.length;
         //构建堆
         buildHeap(arr, length);
         for (int i = length - 1; i > 0; i--) {
             //将堆顶元素与末位元素调换
             int temp = arr[0];
             arr[0] = arr[i];
             arr[i] = temp;
             //数组长度-1 隐藏堆尾元素
             length--;
             //将堆顶元素下沉 目的是将最大的元素浮到堆顶来
             sink(arr, 0, length);
        }
    }
 ​
     private static void buildHeap(int[] arr, int length) {
         for (int i = length / 2; i >= 0; i--) {
             sink(arr, i, length);
        }
    }
 ​
     private static void sink(int[] arr, int index, int length) {
         int leftChild = 2 * index + 1;//左子节点下标
         int rightChild = 2 * index + 2;//右子节点下标
         int present = index;//要调整的节点下标
 ​
         //下沉左边
         if (leftChild < length && arr[leftChild] > arr[present]) {
             present = leftChild;
        }
 ​
         //下沉右边
         if (rightChild < length && arr[rightChild] > arr[present]) {
             present = rightChild;
        }
 ​
         //如果下标不相等 证明调换过了
         if (present != index) {
             //交换值
             int temp = arr[index];
             arr[index] = arr[present];
             arr[present] = temp;
 ​
             //继续下沉
             sink(arr, present, length);
        }
    }
 }
 ​

Exer010Sort08CountSort

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  * 计数排序
  */
 public class Exer010Sort08CountSort {
     public static void main(String[] args) {
         int[] array = { 4, 2, 2, 8, 3, 3, 1 };
         // 找到数组中最大的值 ---> max:8
         int max = findMaxElement(array);
         int[] sortedArr = countingSort(array, max + 1);
         System.out.println("计数排序后的数组: " + Arrays.toString(sortedArr));
    }
     private static int findMaxElement(int[] array) {
         int max = array[0];
         for (int val : array) {
             if (val > max) {
                 max = val;
            }
        }
         return max;
    }
     private static int[] countingSort(int[] array, int range) { //range:8+1
         int[] output = new int[array.length];
         int[] count = new int[range];
         //初始化: count1数组
         for (int i = 0; i < array.length; i++) {
             count[array[i]]++;
        }
         //计数: count2数组,累加次数后的,这里用count2区分
         for (int i = 1; i < range; i++) {
             count[i] = count[i] + count[i - 1];
        }
         //排序:最后数组
         for (int i = 0; i < array.length; i++) {
             output[count[array[i]] - 1] = array[i];
             count[array[i]]--;
        }
         return output;
    }
 ​
 }
 ​

Exer010Sort09BucketSort

 

 

 ​
 import java.util.*;
 ​
 /**
  * 本代码的知识点:
  * 桶排序
  */
 public class Exer010Sort09BucketSort {
     public static void main(String[] args) {
         // 输入元素均在 [0, 10) 这个区间内
         float[] arr = new float[]{0.12f, 2.2f, 8.8f, 7.6f, 7.2f, 6.3f, 9.0f, 1.6f, 5.6f, 2.4f};
         bucketSort(arr);
         printArray(arr);
    }
 ​
     public static void bucketSort(float[] arr) {
         // 新建一个桶的集合
         ArrayList<LinkedList<Float>> buckets = new ArrayList<LinkedList<Float>>();
         for (int i = 0; i < 10; i++) {
             // 新建一个桶,并将其添加到桶的集合中去。
             // 由于桶内元素会频繁的插入,所以选择 LinkedList 作为桶的数据结构
             buckets.add(new LinkedList<Float>());
        }
         // 将输入数据全部放入桶中并完成排序
         for (float data : arr) {
             int index = getBucketIndex(data);
             insertSort(buckets.get(index), data);
        }
         // 将桶中元素全部取出来并放入 arr 中输出
         int index = 0;
         for (LinkedList<Float> bucket : buckets) {
             for (Float data : bucket) {
                 arr[index++] = data;
            }
        }
    }
 ​
     /**
      * 计算得到输入元素应该放到哪个桶内
      */
     public static int getBucketIndex(float data) {
         // 这里例子写的比较简单,仅使用浮点数的整数部分作为其桶的索引值
         // 实际开发中需要根据场景具体设计
         return (int) data;
    }
 ​
     /**
      * 我们选择插入排序作为桶内元素排序的方法 每当有一个新元素到来时,我们都调用该方法将其插入到恰当的位置
      */
     public static void insertSort(List<Float> bucket, float data) {
         ListIterator<Float> it = bucket.listIterator();
         boolean insertFlag = true;
         while (it.hasNext()) {
             if (data <= it.next()) {
                 it.previous(); // 把迭代器的位置偏移回上一个位置
                 it.add(data); // 把数据插入到迭代器的当前位置
                 insertFlag = false;
                 break;
            }
        }
         if (insertFlag) {
             bucket.add(data); // 否则把数据插入到链表末端
        }
    }
 ​
     public static void printArray(float[] arr) {
         for (int i = 0; i < arr.length; i++) {
             System.out.print(arr[i] + ", ");
        }
         System.out.println();
    }
 ​
 }
 ​
 ​

Exer010Sort10RaixSort

 ​
 import java.util.Arrays;
 ​
 /**
  * 本代码的知识点:
  *   基数排序
  */
 public class Exer010Sort10RaixSort {
     public static void main(String[] args) {
         int[] arr = { 53, 3, 542, 748, 14, 214 };
 ​
         // 得到数组中最大的数
         int max = arr[0];// 假设第一个数就是数组中的最大数
         for (int i = 1; i < arr.length; i++) {
             if (arr[i] > max) {
                 max = arr[i];
            }
        }
         // 得到最大数是几位数
         // 通过拼接一个空串将其变为字符串进而求得字符串的长度,即为位数
         int maxLength = (max + "").length();
 ​
         // 定义一个二维数组,模拟桶,每个桶就是一个一维数组
         // 为了防止放入数据的时候桶溢出,我们应该尽量将桶的容量设置得大一些
         int[][] bucket = new int[10][arr.length];
         // 记录每个桶中实际存放的元素个数
         // 定义一个一维数组来记录每个桶中每次放入的元素个数
         int[] bucketElementCounts = new int[10];
 ​
         // 通过变量n帮助取出元素位数上的数
         for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
             for (int j = 0; j < arr.length; j++) {
                 // 针对每个元素的位数进行处理
                 int digitOfElement = arr[j] / n % 10;
                 // 将元素放入对应的桶中
                 // bucketElementCounts[digitOfElement]就是桶中的元素个数,初始为0,放在第一位
                 bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
                 // 将桶中的元素个数++
                 // 这样接下来的元素就可以排在前面的元素后面
                 bucketElementCounts[digitOfElement]++;
            }
             // 按照桶的顺序取出数据并放回原数组
             int index = 0;
             for (int k = 0; k < bucket.length; k++) {
                 // 如果桶中有数据,才取出放回原数组
                 if (bucketElementCounts[k] != 0) {
                     // 说明桶中有数据,对该桶进行遍历
                     for (int l = 0; l < bucketElementCounts[k]; l++) {
                         // 取出元素放回原数组
                         arr[index++] = bucket[k][l];
                    }
                }
                 // 每轮处理后,需要将每个bucketElementCounts[k]置0
                 bucketElementCounts[k] = 0;
            }
        }
         System.out.println(Arrays.toString(arr));//[3, 14, 53, 214, 542, 748]
    }
 ​
 }
 ​

 

 

复杂度

 

 

标签:arr,JAVA,temp,int,length,++,算法,排序,public
From: https://www.cnblogs.com/wuxianfeng023/p/16828330.html

相关文章

  • Java实现rabbitMQ向MQ里推送消息
    配置文件application.properties里配置rabbitMQ的ip和端口,如果没有配置username和password,就是mq安装时默认的用户名密码:spring.rabbitmq.host=127.0.0.1spring.rabbitm......
  • JavaScripts 小脚本实现格式化打印
    consttext=String.raw`{"success":true,"code":0,"message":null,"body":{"items":[{"isNonStandard":false,"productId":1813,"skuNumber":"H00027","manufacturerPart......
  • openssl 全面支持国密SM2/SM3/SM4加密算法
    sm4展示代码/**文件名:https://github.com/liuqun/openssl-sm4-demo/blob/cmake/src/main.c*/#include<stddef.h>#include<stdio.h>#include<stdlib.h>#inclu......
  • open-api 算法实现
    作者:20201303张奕博要求:推荐在openEuler中实现,参考https://www.cnblogs.com/rocedu/p/6012545.html第三节提交相关代码码云(或github)链接(我使用博客园)提交不少于6张编......
  • vue源码分析-diff算法核心原理
    这一节,依然是深入剖析Vue源码系列,上几节内容介绍了VirtualDOM是Vue在渲染机制上做的优化,而渲染的核心在于数据变化时,如何高效的更新节点,这就是diff算法。由于源码中关于d......
  • Java在线诊断工具Arthas快速入门与使用
    场景ArthasArthas是一款线上监控诊断产品,通过全局视角实时查看应用load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用......
  • Java反射之类的字节码对象的三种调用方式和JDBC【多测师】
    类的字节码对象:packagecom.section02;importorg.apache.log4j.Logger;importcom.section01.Student;/***@authorxiaoshu*同一个类在JVM中只存在一份字节码对象*也就是......
  • prim算法(普里姆算法)详解
    了解了什么是最小生成树后,本节为您讲解如何用普里姆(prim)算法查找连通网(带权的连通图)中的最小生成树。普里姆算法查找最小生成树的过程,采用了贪心算法的思想。对于包含N个......
  • 【Java】创建两个分线程,其中一个线程遍历100以内的偶数,另一个线程遍历100以内的奇数
    方式一:写两个类,run方法分别实现classMyThread1extendsThread{@Overridepublicvoidrun(){for(inti=0;i<100;i++){if(i%......
  • [CS] C2-1. 算法
    书名:Algorithmdesign作者:JonKleinberg一、算法基础...二、排序...三、贪心...四、分治...五、动态规划...六、进阶问题6.1最大流问题......