博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java 基本排序
阅读量:4135 次
发布时间:2019-05-25

本文共 5496 字,大约阅读时间需要 18 分钟。

/** * 快排概念: * 快排也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的;在每一轮挑选一个基准元素,并让其他比它大的元素移动到数列一边, * 比它小的元素移动到数组的另一边,从而将数组拆成两个部分,这种思路叫做分治法 * * 时间复杂度: * 原数组在分支法的思想下,没一轮都会被拆分为两部分,所以遍历的轮数为logn,每一轮的比较和交换需要把数组全部遍历一遍, * 这个时间复杂度是O(n),所以总的平均时间复杂度是O(nlogn) * 但是如果将原本逆序的数列排序成顺序数列,整个数列并没有被分成两半,每一轮都只确定来基准元素的位置,数列的第一个元素要么是最大值要么是最小值, * 无法发挥分支法的优势,这个时候快速排序需要进行n轮,时间复杂度退化为O(n平方)。 * 解决思路是:随机选择一个元素作为基准元素 * *//**     * 递归的方式     * @param arr     * @param startIndex     * @param endIndex     */    public static void quickSort(int[] arr,int startIndex,int endIndex){        if(arr == null || startIndex >= endIndex){            return;        }        //得到基准元素位置        int pivotIndex = partition(arr,startIndex,endIndex);        //根据基准元素位置分成两部分进行递归        quickSort(arr,startIndex,pivotIndex - 1);        quickSort(arr,pivotIndex + 1,endIndex);    }    /**     * 循环方式     * 引入一个存储Map类型元素的栈,用于存储每一次交换时的起始下标和结束下标     * 每一次循环,都会让栈顶元素出栈,通过partition方法方法进行分支,并且按照基准元素的位置分成左右两部分,左右两部分再分别入栈。     * 当栈为空时,说明排序已经完毕,推出循环     */    public static void quickSort2(int[] arr,int startIndex,int endIndex){        Stack
> stack = new Stack<>(); Map
root = new HashMap<>(); root.put("startIndex",startIndex); root.put("endIndex",endIndex); stack.push(root); while (!stack.isEmpty()){ Map
item = stack.pop(); int pivotIndex = partition(arr,item.get("startIndex"),item.get("endIndex")); if(item.get("startIndex")
left = new HashMap<>(); left.put("startIndex",item.get("startIndex")); left.put("endIndex",pivotIndex - 1); stack.push(left); } if(pivotIndex + 1 < item.get("endIndex")){ Map
right = new HashMap<>(); right.put("startIndex",pivotIndex + 1); right.put("endIndex",item.get("endIndex")); stack.push(right); } } } /** * 选择基准元素位置:(单边循环法) * 首先选定基准元素 pivot,同时设置一个mark指针指向数列起始位置,这个mark指针代表小于基准元素的区域边界 * 接下来从基准元素的下一个位置开始遍历数组 * 如果遍历到的元素大于基准元素,则继续往下遍历 * 如果遍历到的元素小于基准元素,需要做两件事情。 * 第一:将mark元素向右移动1位,因为小于pivot基准元素的区域边界增大了1 * 第二:将遍历到的最新的元素和mark位置指针所在的元素互换位置,因为最新遍历的元素归属于小于pivot的区域 * @param arr * @param startIndex * @param endIndex * @return */ public static int partition(int[] arr,int startIndex,int endIndex){ int pivot = arr[startIndex]; int mark = startIndex; for(int i = startIndex + 1;i <= endIndex ;i++){ if(arr[i]
=r) return; //防止 p和r过大,(p+r)溢出 int q = p +(r- p)/2; //分治递归 mergeSort(data,p,q); mergeSort(data,q + 1,r); // 将A[p...q]和A[q+1...r]合并为A[p...r] merge(data,p,q,r);}private static void merge(int[] data,int p,int q,int r){ int i= p; int j = q +1; int k = 0; int[] temp = new int[r-p + 1]; while (i<=q && j<=r){ if(data[i]<=data[j]){ temp[k++] = data[i++]; }else { temp[k++] = data[j++]; } } // 判断哪个子数组中有剩余的数据 int start = i; int end = q; if(j<=r){ start = j; end = r; } // 将剩余的数据拷贝到临时数组tmp while (start <= end){ temp[k++]=data[start ++]; } //将临时变量拷贝回a[p..r] for (i=0;i<=r-p;i++){ data[p+i] = temp[i]; }}
/** * 冒泡排序,基本优化 * 冒泡排序思想:把相邻两个元素两两比较,当一个元素大于右侧相邻元素时,交换它们的位置,当一个元素小于或等于右侧相邻元素时,位置不变。一次冒泡会让至少一个元素移动到它应该在的位置,重复n次,就完成了n个数据的排序工作 * 为原地稳定算法,时间复杂度为n²,最好时间复杂度为n,平均和最坏情况为n² * 采用双循环进行排序,外部循环控制所有回合,内部循环实现每一轮的冒泡处理,先进行元素比较,再进行元素交换 * * @param arr */public static void bubbleSort(int[] arr) {    for (int i = 0; i < arr.length - 1; i++) {        //有序标记,每一轮的初始致都为true        boolean isSorted = true;        for (int j = 0; j < arr.length - i - 1; j++) {            if (arr[j] > arr[j + 1]) {                int temp = arr[j];                arr[j] = arr[j + 1];                arr[j + 1] = temp;                //因为有元素交换,所以是无序的                isSorted = false;            }        }        if (isSorted) {            break;        }    }}/** * 冒泡排序优化 * sortBorder是无序数列的边界,在每一轮排序过程中,处于sortBorder之后的元素不需要进行比较了,肯定是有序的 * @param arr */public static void bubbleSort2(int[] arr) {    //记录最后一次交换的位置    int lastExchangeIndex = 0;    //无序数列的边界,每次比较只需要比较到此为止    int sortBorder = arr.length - 1;    for (int i = 0; i < arr.length; i++) {        //有序标记,每一轮的初始致都为true        boolean isSorted = true;        for (int j = 0; j < sortBorder; j++) {            if (arr[j] > arr[j + 1]) {                int temp = arr[j];                arr[j] = arr[j + 1];                arr[j + 1] = temp;                //因为有元素交换,所以是无序的                isSorted = false;                //更新为最后一次交换元素的位置                lastExchangeIndex = j;            }        }        sortBorder = lastExchangeIndex;        if (isSorted) {            break;        }    }}
/** * 插入排序 * 首先我们将数组中数据分为两个区间,已排序和未排序区间。初始化时已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序算法中的元素,在已排序算法中找到合适的插入位置将其插入 * 原地稳定算法,时间复杂度为O(n2),但它赋值次数比冒泡的少(插入赋值一次,冒泡3次),所以效率比冒泡的高 * @param data */public static void insertSort(int[] data){    if(data == null || data.length <= 1) return;    for (int i=1;i
=0 ;j--){ if(data[j]>val){ //数据移动 data[j+1] = data[j]; }else { break; } } //找到位置插入 data [j + 1] = val; }}public static void main(String[] args) { int[] data ={6,11,3,9,8}; quickSort(data); System.out.println("快排结果为"+ Arrays.toString(data)); data =new int[]{6,11,3,9,8}; mergeSort(data,0,data.length-1); System.out.println("归并排序结果为"+ Arrays.toString(data)); data =new int[]{6,11,3,9,8}; bubbleSort(data); System.out.println("冒泡排序结果为"+ Arrays.toString(data)); data =new int[]{6,11,3,9,8}; insertSort(data); System.out.println("插入排序结果为"+ Arrays.toString(data));}

转载地址:http://dhsvi.baihongyu.com/

你可能感兴趣的文章
JAVA给网站添加爬虫数据-超简单(jsoup)新闻图片数据
查看>>
linux安装nodejs
查看>>
@JsonFormat时间误差的坑,相差8小时
查看>>
Linux将服务设置为开机自启,linux启动VUE项目,设置VUE项目自启
查看>>
JAVA中判断数据不为空后执行数据操作、防止空指针报错的工具类,safes工具类
查看>>
TypeError: Cannot read property ‘parseComponent‘ of undefined解决办法-VUE
查看>>
kingbase逻辑备份报错解决-sys_dump:
查看>>
java8-Stream流的介绍\创建\基本操作\
查看>>
我们写的程序就像我们的孩子
查看>>
JAVA文件批量下载打成压缩包
查看>>
JAVA列表转树状结构-列表拼装树状tree,递归,hutool,效率
查看>>
Linux解决上传的文件访问不到,nginx访问文件403,新建的文件夹没有读写权限
查看>>
io.minio.errors.ErrorResponseException: Access denied
查看>>
使用反射在 ArrayList<Integer> 集合中添加一个字符串数据;
查看>>
mysql 中union和union的区别和使用方法
查看>>
mysql 数据库三大设计结构,三大范式概念
查看>>
mysql中四大连接 内连接、左外连接、右外连接、外连接
查看>>
java中 @Test注解的使用和其他成员
查看>>
使用java将mp3文件写入mysql数据库中
查看>>
使用java将数据库文件复制到本地磁盘中
查看>>