算法 - 排序算法 (算法学习)(冒泡、选择、插入、希尔、快排、归并)

1)冒泡排序

在这里插入图片描述

1.1 图解演示

在这里插入图片描述

2)选择排序

import java.text.SimpleDateFormat;
import java.util.Date;/*** 选择排序*/
public class chooseSort {public static void selectSort(int[] arr){for (int i = 0; i < arr.length; i++) {int minIndex = i;int min = arr[i];for (int j = i+1; j < arr.length; j++) {if (min > arr[j]){ //说明最小值不是min,然后重置min = arr[j];minIndex = j;}}//交换arr[minIndex] = arr[i];arr[i] = min;}}public static void main(String[] args) {int arr []  = new int[80000];for (int i = 0; i < arr.length; i++) {arr[i] = (int)(Math.random() * 800000);}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String data1Str = simpleDateFormat.format(date1);System.out.println("排序前时间:"+ data1Str);selectSort(arr);Date date2 = new Date();String date2Str = simpleDateFormat.format(date2);System.out.println("排序后时间:"+ date2Str);//System.out.println(Arrays.toString(arr));}
}

3)插入排序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import java.text.SimpleDateFormat;
import java.util.Date;public class InsertSort {public static void insertSort(int [] arr){for (int i = 1; i < arr.length; i++) {int insertVal = arr[i];int insertIndex = i-1;//arr[1]前面这个数的下标//给insertVal找到插入位置//insertIndex>=0保证给insertVal插入的位置不越界//insertVal < arr[insertIndex]待插入的数,还没有找到插入的位置//就需要arr[insertIndex]后移while(insertIndex >= 0 && insertVal < arr[insertIndex]){arr[insertIndex+1] = arr[insertIndex];insertIndex --;}//出来就是找到插入的位置,即insertIndex+1arr[insertIndex+1] = insertVal;}}public static void main(String[] args) {int [] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int)(Math.random()*800000);}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String format1 = simpleDateFormat.format(date1);System.out.println(format1);insertSort(arr);Date date2 = new Date();String format2 = simpleDateFormat.format(date2);System.out.println(format2);//System.out.println(Arrays.toString(arr));}
}

4)希尔排序(插入排序改进版)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.1希尔的交换法

import java.text.SimpleDateFormat;
import java.util.Date;/*** 希尔排序(缩小增量排序),交换的速度并不快*/
public class SellSort {public static void sellSort(int [] arr){//第一轮排序将10个数据分成5组int temp = 0;int gap = arr.length/2;while(gap>=1) {for (int i = gap; i < arr.length; i++) {//遍历各组中所有元素(共五组,每组两个元素),步长为5for (int j = i - gap; j >= 0; j -= gap) {//如果当前元素大于加上步长元素交换if (arr[j] > arr[j + gap]) {temp = arr[j];arr[j] = arr[j + gap];arr[j + gap] = temp;}}}gap = gap/2;}}public static void main(String[] args) {int [] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int)(Math.random()*800000);}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String format1 = simpleDateFormat.format(date1);System.out.println(format1);sellSort(arr);Date date2 = new Date();String format2 = simpleDateFormat.format(date2);System.out.println(format2);}
}

**加粗样式**

4.2希尔的移位法

import java.text.SimpleDateFormat;
import java.util.Date;/*** 希尔排序(缩小增量排序),交换的速度并不快*///移位法public static void sellSort2(int [] arr){//第一轮排序将10个数据分成5组int temp = 0;int gap = arr.length/2;while(gap >= 1) {for (int i = gap; i < arr.length; i++) {int insertVal = arr[i];int insertIndex = i - gap;//移位找位置while(insertIndex >= 0 && arr[insertIndex] > arr[i]){arr[i] = arr[insertIndex];insertIndex -= gap;}//插入if (insertIndex + gap != i){arr[insertIndex+ gap] = insertVal;}}gap = gap/2;}}public static void main(String[] args) {int [] arr = new int[80000];for (int i = 0; i < 80000; i++) {arr[i] = (int)(Math.random()*800000);}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String format1 = simpleDateFormat.format(date1);System.out.println(format1);sellSort2(arr);Date date2 = new Date();String format2 = simpleDateFormat.format(date2);System.out.println(format2);//System.out.println(Arrays.toString(arr));}
}

在这里插入图片描述

可以看到希尔排序的移位法的效率大大提高。当你改成8w、80w都是可以1秒出结果,但是插入排序80w需要很长时间大概几分钟。

5)快速排序

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package sort;import java.text.SimpleDateFormat;
import java.util.Date;public class QuickSort {public static void quickSort(int [] arr,int left,int right){int l = left; //左下标int r = right; //右下标int pivot = arr[(left+right)/2];//while循环的目的是让比pivot小的放到左边,大的放到右边int temp = 0;while (r > l){while (arr[l] < pivot){ //在pivot左边一直找,找到大于等于pivot的值l += 1;}while(arr[r] > pivot){//在pivot右边一直找,找到小于等于pivot的值r -= 1;}//如果l>=r成立,说明排序成功if (l >= r){break;}//交换temp = arr[l];arr[l] = arr[r];arr[r] = temp;//交换完成后发现值arr[l] = pivot,需要往前再走一步if (arr[l] == pivot){l++;}//交换完成后发现值arr[r] = pivot,需要往前再走一步if (arr[r] == pivot){r--;}}//如果l == r,必须让l++,r--,否则死循环出不去if (l == r){l++;r--;}//向左递归if (left < r){quickSort(arr,left,r);}//向右递归if (right > l){quickSort(arr,l,right);}}public static void main(String[] args) {int [] arr = new int[8000000];for (int i = 0; i < 8000000; i++) {arr[i] = (int)(Math.random()*80000000);}Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String format1 = simpleDateFormat.format(date1);System.out.println(format1);quickSort(arr,0,arr.length-1);Date date2 = new Date();String format2 = simpleDateFormat.format(date2);System.out.println(format2);//System.out.println(Arrays.toString(arr));}
}

在这里插入图片描述

800w数据3秒

上面代码听完课,研究一下午还是没太懂尤其是递归那块,于是又查了好多资料学习

package sort;import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;public class QuickSort {public static void quickSort1(int[] arr, int start, int end) {//1.找到中轴getIndex()//2.左递归//3.右递归if (start < end) {int index = getIndex(arr, start, end);quickSort1(arr, start, index - 1);quickSort1(arr, index + 1, end);}}//找中轴又分为://1.取一个中轴,随便取//2.(如果中轴是第一个位置)那么就先从右往左找,找到小于等于中轴的数,然后把找到的数赋值给arr[start]//3.从左往右找,找到大于等于中轴的数,把找到的数赋给arr[end]//4.最后再把pivot赋给arr[start]//5.返回startpublic static int getIndex(int[] arr, int start, int end){int pivot = arr[start];while (start < end){//从右往左找while (arr[end] >= pivot && start < end){end --;}arr[start] = arr[end];while(arr[start] <= pivot && start < end){start++;}arr[end] = arr[start];}arr[start] = pivot;return start;}public static void main(String[] args) {int[] arr = new int[]{-1,0,5,2,8,-1,0,0,0};
//        for (int i = 0; i < 4; i++) {
//            arr[i] = (int)(Math.random()*800000);
//        }Date date1 = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");String format1 = simpleDateFormat.format(date1);System.out.println(format1);quickSort1(arr, 0, arr.length - 1);Date date2 = new Date();String format2 = simpleDateFormat.format(date2);System.out.println(format2);System.out.println(Arrays.toString(arr));}
}

6)归并排序

在这里插入图片描述
在这里插入图片描述

package sort;import java.util.Arrays;public class MergeSort {/**** @param arr 排序的原始数组* @param start 左边初始索引* @param end   右边初始索引* @param mid   中间索引* @param temp  中转的数组*/public static void merge(int[] arr, int start, int end, int mid,int[] temp){int i = start; //初始化i,左边有序序列的初始索引int j = mid + 1;   //初始化j,右边有序序列的初始索引int t = 0; //指向temp数组的当前索引//(1)//先把左右两边(有序)的数据按照规则填充到temp数组//直到左右两边的有序序列,有一边处理完毕while (i <= mid && j <= end){//如果左边有序序列的当前元素,小于等于右边有序序列的当前元素//即将左边的当前元素,拷贝到temp数组//然后t++,i++if (arr[i] <= arr[j]){temp[t] = arr[i];t++;i++;}else {//反之,右边有序序列当前元素小于左边,将右边有序序列当前元素拷贝到temptemp[t] = arr[j];t++;j++;}}//(2)//把有剩余数据的一边的数据依次填充到tempwhile (i <= mid){//说明左边有序序列剩余元素还有剩余,全部填充到temptemp[t] = arr[i];t++;i++;}while (j <= end){//说明右边有序序列剩余元素还有剩余,全部填充到temptemp[t] = arr[j];t++;j++;}//(3)//将temp元素拷贝到arr//注意并不是每次都拷贝所有t = 0;int tempLeft = start;//while (tempLeft <= end){//第一次合并tempLeft = 0;right = 1arr[tempLeft] = temp[t];t++;tempLeft ++;}}//分+合方法public static void mergeSort(int[] arr,int start,int end,int[] temp){if (start < end){int mid = (start+end)/2; //中间索引//向左递归进行分解mergeSort(arr,start,mid,temp);//向右递归进行分解mergeSort(arr,mid+1,end,temp);//合并merge(arr, start,end,mid,temp);}}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));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/437590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【转】1.4 Magento2语法讲解

M2不是一个标准的MVC架构。 这是m2的app/code/Magento/Catalog插件代码。 可以看到&#xff0c;它有Controller,也有Model,也有view. 奇怪的是,在Controller找不到调用模版的代码。 这是因为我们之前讲过,m2的页面都是用xml写的&#xff0c;xml里是由若干个block组成的。block里…

【转】1.5 运行原理剖析

我们不讲底层架构,核心原理,太枯燥&#xff0c;也记不住&#xff0c;没必要。 毕竟不是人人都要当架构师。 我们从M2的模式说起。 理解了他的模式,就知道了他的原理。 M2有3种模式, 默认模式(default)开发模式(developer)生产模式(production) 默认模式 安装完成后&#xf…

SparkStreaming简介 - 与第一个Spark实时计算程序,使用netcat来写数据 - wordcount

官方文档 Spark Streaming 火花流是spark API的扩展&#xff0c;它支持可伸缩、高吞吐量、容错的实时数据流处理。 数据可以从多种来源(如Kafka、Flume、Kinesis或tcp套接字)中摄取&#xff0c;并且可以使用用高级函数表示的复杂算法进行处理&#xff0c;例如map, reduce, jo…

【转】老邹说Magento的前世今生

文章目录[隐藏] Magento Commerce的历史Magento 2版本历史Magento电子商务的特点和功能Magento市场Magento认证Magento事件为什么Magento统治电子商务领域 想要深入了解magento&#xff0c;我们有必要回顾一下Magento的前世今生&#xff0c;看它是如何一步步成长起来的。 为什…

【转】Magento2 安装系列一 虚拟机、CentOS7 安装

前言 最近打算在Windows10安装最新的magento2.3&#xff0c;由于mg2.3对Windows支持不太友好&#xff0c;所以就打算在Windows10安装虚拟机&#xff0c;虚拟机安装CentOS7版本的Linux&#xff0c;Linux安装Lnmp环境&#xff0c;最终安装Magento2.3.虚拟机选择与安装 我这边打算…

SparkStreaming -Kafka数据源

SparkStreaming处理kafka作为数据源 所以我们要创建的是kafka的Dstream&#xff0c;那么就要使用到KafkaUtils下的createStream&#xff0c;先来看一下ctrl点进去查看&#xff0c;然后来写参数 package date_10_16_SparkStreamingimport org.apache.spark.SparkConf import or…

SparkStreaming - 无状态与有状态 updataStateByKey

无状态与有状态 简单来说&#xff0c;无状态就是每个采集周期分别采集&#xff0c;并不会把前面的采集周期的数据一起计算 有状态就是&#xff1a;把前面采集周期的也算进来&#xff0c; 比如wordcount&#xff0c;无状态统计的就是每个采集周期内的个数&#xff0c;有状态的…

flink(一个流处理,一个批处理)

流处理&#xff0c;这里用netcat来完成 package com.smalltiger.flinkWCimport org.apache.flink.api.java.utils.ParameterTool import org.apache.flink.streaming.api.scala._/*** Created by smalltiger on 2019/11/6.* flink基于流处理的一个WordCount统计*/ object Stre…

volatile学习(可见性,不保证原子性,禁止指令重排(双端检索机制))

volatile是java虚拟机提供的轻量级的同步机制&#xff1a; 1.保证可见性&#xff1a;线程之间可见性(及时通知) 2.不保证原子性 3.禁止指令重排 先了解一下jvm同步 由于JVM运行程序的实体是线程&#xff0c;而每个线程创建时JVM都会为其创建一个工作内存&#xff08;或者称为…

CAS(比较并交换)学习CAS实现原子性+volatile实现可见性,cas与synchronized比较的优缺点

1、CAS底层原理&#xff1f; 自旋锁(cas思想)unsafe类&#xff0c;保证原子性靠的是unsafe类 1.首先可以看到&#xff1a; atomicInteger.getAndIncrement();getAndIncrement()的底层是 public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset,…

cas引出的ABA问题?如何解决?- 理解原子引用、时间戳(版本号)原子引用

ABA问题&#xff1a; 假如有两个线程1&#xff0c;2&#xff1b; cas下&#xff1a;1.线程取值完等待&#xff0c;2线程取值并把A改成B&#xff0c;有把B改成A&#xff0c;这是1线程执行会任务A还是原来的A没有发生改变&#xff0c;如果不在乎中间结果&#xff0c;只看收尾&am…

java -锁(公平、非公平锁、可重入锁【递归锁】、自旋锁)

1.公平锁、非公平锁 2.可重入锁&#xff08;递归锁&#xff09; 3.自旋锁 AtomicReference atomicReference new AtomicReference();//原子引用线程下面代码5秒钟自旋了10万次&#xff0c;还是很消耗CPU的 package HighConcurrency;import java.util.concurrent.TimeUnit; imp…

CountDownLatch,同步辅助类

public class CountDownLatchextends Object一个同步辅助类&#xff0c;在完成一组正在其他线程中执行的操作之前&#xff0c;它允许一个或多个线程一直等待。 假设定义一个计数器为 5。每个线程完成任务后计数减1计数器减为 0 则通知等待的线程。 用给定的计数 初始化 Count…

CyclicBarrier-同步辅助类

与CountDownLatch相反&#xff0c;CyclicBarrier是做加法 public class CyclicBarrierextends Object一个同步辅助类&#xff0c;它允许一组线程互相等待&#xff0c;直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中&#xff0c;这些线程必…

阻塞队列-BlockningQueue

阻塞队列的前言介绍引用于https://www.cnblogs.com/aspirant/p/8657801.html&#xff0c;写的挺好有兴趣可以看一看 一. 前言 在新增的Concurrent包中&#xff0c;BlockingQueue很好的解决了多线程中&#xff0c;如何高效安全“传输”数据的问题。通过这些高效并且线程安全的…

多线程下的生产者消费者(一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮)

在使用Lock之前&#xff0c;我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了。配合Object的wait()、notify()系列方法可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法&#xff0c;与Lock配合可以实现等待/通知模式 下面用的是lock锁 …

阻塞队列,来写生产者消费者,生产一个消费一个

用阻塞队列来写&#xff0c;就不需要程序员来关心什么时候阻塞线程await&#xff0c;什么时候唤醒线程notify&#xff08;&#xff09;。 类似消息中间件 package JUC;import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import…

线程池ThreadPool,线程池底层ThreadPoolExecutor方法七大参数,拒绝策略,以及实际开发中高并发下用到哪个线程池?

为什么要用线程池 基本的三个线程池的底层就是ThreadPoolExecutor类 ExecutorService threadPool Executors.newFixedThreadPool(int);//固定线程数的线程池&#xff0c;&#xff0c;执行长期的任务&#xff0c;性能好 ExecutorService threadPool Executors.newSingleThrea…

【转】2.1.1 购买阿里云服务器(Ubuntu系统)

购买阿里云服务器 优惠购买链接 戳我购买 Cpu和内存 M2对服务器配置要求比较高&#xff0c; cpu要大于等于1, 内存要大于等于2 选择Ubuntu镜像 最好用官方提供的公共镜像&#xff0c;不要用第三方的。 其他的配置 其他的配置按你自己的需求来选择。 控制台 购买完成后…

死锁编码及定位分析(故障排查)

什么是死锁&#xff1f; 在Java中使用多线程&#xff0c;就会有可能导致死锁问题。死锁会让程序一直卡住&#xff0c;不再程序往下执行。我们只能通过中止并重启的方式来让程序重新执行。 造成死锁的原因&#xff1a; 当前线程拥有其他线程需要的资源当前线程等待其他线程已…