我们举一个具体的案例来说明冒泡算法。我们将五个无序的数: 3,9,-1,10,20.。使用冒泡排序算法将排成一个从小到大的有序数列。
冒泡排序规则小结:
1. 一共进行数组的大小-1次大的循环
2. 每一趟排序的次数在逐渐的减少
3. 如果我们发现在某趟偶排序中,没有发生一次交换,可以提前结束冒泡排序,这个就是优化
package com.sort;
/**
* 冒泡排序
* DuanXS
*/
public class BubbleSort {
public static void main(String[] args) {
//确定数组
int arr[] = {
3,9,-1,10,-2};
}
}
//为了容器理解,我们把冒泡排序的演变过程,给大家展示出来
//第一趟就是把最大的数组排在最后
//临时变量
int temp = 0;
for (int j = 0; j < arr.length-1; j++){
//如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第一趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第二趟排序,就是将第二大的数排在倒数第二位
for (int j = 0; j < arr.length-1-1; j++){
//如果前面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第三趟排序,就是将第三大的数排在倒数第三位
for (int j = 0; j<arr.length-1-2; j++){
//如果卡面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第三趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第四趟排序,就是将第四大的数排在倒数第四位
for (int j = 0; j<arr.length-1-3; j++){
//如果卡面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第四趟排序后的数组");
System.out.println(Arrays.toString(arr));
//找到规律 简化代码
for (int i = 0; i <arr.length-1 ; 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+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
}
//第一趟就是把最大的数组排在最后
//临时变量
int temp = 0;
//标识变量,表示是否进行过交换
boolean flag = false;
/* for (int j = 0; j < arr.length-1; j++){
//如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]){
@@ -69,13 +71,22 @@ public class BubbleSort {
for (int j = 0; j arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
//在一趟排序中,一次交换都没有发生过
if (!flag){
break;
}else {
//重置flag,进行下次判断
flag = false;
}
}
}
//将前面的冒泡排序算法,封装成一个方法
public static void bubbleSort(int[] arr){
//为了容器理解,我们把冒泡排序的演变过程,给大家展示出来
//第一趟就是把最大的数组排在最后
//临时变量
int temp = 0;
//标识变量,表示是否进行过交换
boolean flag = false;
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j<arr.length-1-i; j++){
//如果卡面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//System.out.println("第"+(i+1)+"趟排序后的数组");
//System.out.println(Arrays.toString(arr));
//在一趟排序中,一次交换都没有发生过
if (!flag){
break;
}else {
//重置flag,进行下次判断
flag = false;
}
System.out.println("排序前");
System.out.println(Arrays.toString(arr));
//测试冒泡排序
bubbleSort(arr);
System.out.println("排序后");
System.out.println(Arrays.toString(arr));
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[8];
for (int i = 0; i < 8; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
//测试这个数组是否是随机的
System.out.println(Arrays.toString(arr));
//测试排序前的时间
Date date1 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta = simpleDateFormat.format(date1);
System.out.println("排序前的时间"+deta);
//测试排序后的时间
Date date2 = new Date();
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序后的时间"+deta2);
package com.sort;
import javax.xml.crypto.Data;
import java.sql.Array;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.logging.SimpleFormatter;
/**
* 冒泡排序
* DuanXS
*/
public class BubbleSort {
public static void main(String[] args) {
/* //确定数组
int arr[] = {3,9,-1,10,-2};
System.out.println("排序前");
System.out.println(Arrays.toString(arr));*/
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
//测试这个数组是否是随机的
// System.out.println(Arrays.toString(arr));
//测试排序前的时间
Date date1 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta = simpleDateFormat.format(date1);
System.out.println("排序前的时间"+deta);
//测试冒泡排序
bubbleSort(arr);
//测试排序后的时间
Date date2 = new Date();
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序后的时间"+deta2);
/*System.out.println("排序后");
System.out.println(Arrays.toString(arr));*/
//为了容器理解,我们把冒泡排序的演变过程,给大家展示出来
//第一趟就是把最大的数组排在最后
//临时变量
int temp = 0;
//标识变量,表示是否进行过交换
boolean flag = false;
/* for (int j = 0; j < arr.length-1; j++){
//如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第一趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第二趟排序,就是将第二大的数排在倒数第二位
for (int j = 0; j < arr.length-1-1; j++){
//如果前面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第三趟排序,就是将第三大的数排在倒数第三位
for (int j = 0; j arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第三趟排序后的数组");
System.out.println(Arrays.toString(arr));
//第四趟排序,就是将第四大的数排在倒数第四位
for (int j = 0; j arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第四趟排序后的数组");
System.out.println(Arrays.toString(arr));*/
/* //找到规律 简化代码
for (int i = 0; i arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
System.out.println("第"+(i+1)+"趟排序后的数组");
System.out.println(Arrays.toString(arr));
//在一趟排序中,一次交换都没有发生过
if (!flag){
break;
}else {
//重置flag,进行下次判断
flag = false;
}
}*/
}
//将前面的冒泡排序算法,封装成一个方法
public static void bubbleSort(int[] arr){
//为了容器理解,我们把冒泡排序的演变过程,给大家展示出来
//第一趟就是把最大的数组排在最后
//临时变量
int temp = 0;
//标识变量,表示是否进行过交换
boolean flag = false;
for (int i = 0; i <arr.length-1 ; i++) {
for (int j = 0; j<arr.length-1-i; j++){
//如果卡面的数比后面的数大,则交换
if (arr[j] > arr[j+1]){
flag = true;
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
//System.out.println("第"+(i+1)+"趟排序后的数组");
//System.out.println(Arrays.toString(arr));
//在一趟排序中,一次交换都没有发生过
if (!flag){
break;
}else {
//重置flag,进行下次判断
flag = false;
}
}
}
}
原始数据:101,34,119,1
第一轮排序:1,34,119,101
第二轮排序:1,34,119,101
第三轮排序:1,34,101,119
1.(说明:一共有几个数,就是几个数-1轮排序)
2.每一轮得循环得,又是一个循环得规则(代码)
2.1先假定当前找个数是最小数
2.2然后和后面得每个数进行比较,如果发现有比当前更小得数,就重新确定最小数,并得到下标
2.3当遍历到数组得最后时,就得到本轮最小数和下标
2.4交换【代码】
package com.sort;
public class SelectSort {
public static void main(String[] args) {
}
/**
* 选择排序
* 使用逐步推导得方式来讲解选择排序
* 第一轮
* 原始的数组:101,34,119,1
* 第一轮排序:1,34,119,101
* 算法的思想 先简单———》再复杂,就是可以把一个复杂算法,拆分成简单的问题——》逐步解决
* DuanXS
*/
public static void selectSort(int [] arr){
}
}
public class SelectSort {
public static void main(String[] args) {
int [] arr = {
101,34,119,1};
}
public static void selectSort(int [] arr){
//第一轮
int minIndex = 0;
int min = arr[0];
for (int j = 0+1; j <arr.length ; j++) {
//如果min》arr[j] 说明假定的最小值,并不是最小的
if (min > arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
}
//将最小值,放到arr[0],及交换
arr[minIndex] = arr[0];
arr[0] = min;
//将最小值,放到arr[0],及交换
arr[minIndex] = arr[0];
arr[0] = min;
System.out.println("第一轮后~~");
System.out.println(Arrays.toString(arr));
public static void main(String[] args) {
int [] arr = {
101,34,119,1};
System.out.println("排序前");
System.out.println(Arrays.toString(arr));
selectSort(arr);
}
//第二轮
minIndex = 1;
min = arr[1];
for (int j = 1+1; j <arr.length ; j++) {
//如果min》arr[j] 说明假定的最小值,并不是最小的
if (min > arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
arr[minIndex] = arr[1];
arr[1] = min;
System.out.println("第二轮后~~");
System.out.println(Arrays.toString(arr));
//将最小值,放到arr[0],及交换
arr[minIndex] = arr[0];
arr[0] = min;
if (minIndex != 0) {
arr[minIndex] = arr[0];
arr[0] = min;
}
System.out.println("第一轮后~~");
System.out.println(Arrays.toString(arr));
//将最小值,放到arr[0],及交换
arr[minIndex] = arr[1];
arr[1] = min;
if (minIndex != 1) {
arr[minIndex] = arr[1];
arr[1] = min;
}
System.out.println("第二轮后~~");
System.out.println(Arrays.toString(arr));
}
//第三轮
minIndex = 2;
min = arr[2];
for (int j = 2+1; j <arr.length ; j++) {
//如果min》arr[j] 说明假定的最小值,并不是最小的
if (min > arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != 2) {
arr[minIndex] = arr[2];
arr[2] = min;
}
System.out.println("第三轮后~~");
System.out.println(Arrays.toString(arr));
//在推到过程中,发现规律,因此用一个for循环来解决
for (int i = 0; i <arr.length-1 ; i++) {
//第i轮
int minIndex = i;
int min = arr[i];
for (int j = i+1; j <arr.length ; j++) {
//如果min》arr[j] 说明假定的最小值,并不是最小的
if (min > arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
System.out.println("第"+(i+1)+"轮后~~");
System.out.println(Arrays.toString(arr));
}
//这里是从小到大的 如果想从大到小 这里只需要把 min > arr[j] 大于号换成小于号
if (min > arr[j]){
//重置min
min = arr[j];
//int [] arr = {101,34,119,1};
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
//System.out.println("排序前");
//System.out.println(Arrays.toString(arr));
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间"+deta2);
selectSort(arr);
//System.out.println("排序后");
//System.out.println(Arrays.toString(arr));
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class SelectSort {
public static void main(String[] args) {
//int [] arr = {101,34,119,1};
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
//System.out.println("排序前");
//System.out.println(Arrays.toString(arr));
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间"+deta2);
selectSort(arr);
//System.out.println("排序后");
//System.out.println(Arrays.toString(arr));
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
}
/**
* 选择排序
* 使用逐步推导得方式来讲解选择排序
* 第一轮
* 原始的数组:101,34,119,1
* 第一轮排序:1,34,119,101
* 算法的思想 先简单———》再复杂,就是可以把一个复杂算法,拆分成简单的问题——》逐步解决
*
* DuanXS
*/
public static void selectSort(int [] arr){
//在推到过程中,发现规律,因此用一个for循环来解决
//选择排序时间复杂度是0(n^2)
for (int i = 0; i <arr.length-1 ; i++) {
//第i轮
int minIndex = i;
int min = arr[i];
for (int j = i+1; j <arr.length ; j++) {
//如果min》arr[j] 说明假定的最小值,并不是最小的
//这里是从小到大的 如果想从大到小 这里只需要把 min > arr[j] 大于号换成小于号
if (min > arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != i) {
arr[minIndex] = arr[i];
arr[i] = min;
}
// System.out.println("第"+(i+1)+"轮后~~");
// System.out.println(Arrays.toString(arr));
}
/*
//第一轮
int minIndex = 0;
int min = arr[0];
for (int j = 0+1; j arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != 0) {
arr[minIndex] = arr[0];
arr[0] = min;
}
System.out.println("第一轮后~~");
System.out.println(Arrays.toString(arr));
//第二轮
minIndex = 1;
min = arr[1];
for (int j = 1+1; j arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != 1) {
arr[minIndex] = arr[1];
arr[1] = min;
}
System.out.println("第二轮后~~");
System.out.println(Arrays.toString(arr));
//第三轮
minIndex = 2;
min = arr[2];
for (int j = 2+1; j arr[j]){
//重置min
min = arr[j];
//重置minIndex
minIndex = j;
}
}
//将最小值,放到arr[0],及交换
if (minIndex != 2) {
arr[minIndex] = arr[2];
arr[2] = min;
}
System.out.println("第三轮后~~");
System.out.println(Arrays.toString(arr));
*/
}
}
package com.sort;
public class InsertSort {
public static void main(String[] args) {
int [] arr = {
101,34,119,1};
}
/**
* 插入排序
* 使用逐步推导方式来讲解,便于理解
*
*/
public static void insertSort(int[] arr){
}
}
public static void insertSort(int[] arr){
//实用逐步推到的方法来讲解,便于理解
//第一轮 {101,34,119,1}; =》 {34,101,119,1}
//定义待插入的数
int insertVal = arr[1];
//即arr[1]的前面这个数的下标
int insertIndex = 1-1;
}
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第一轮插入后");
System.out.println(Arrays.toString(arr));
public static void main(String[] args) {
int [] arr = {
101,34,119,1};
insertSort(arr);
}
//第二轮
//定义待插入的数
insertVal = arr[2];
//即arr[1]的前面这个数的下标
insertIndex = 2-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第二轮插入后");
System.out.println(Arrays.toString(arr));
//第三轮
//定义待插入的数
insertVal = arr[3];
//即arr[1]的前面这个数的下标
insertIndex = 3-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第三轮插入后");
System.out.println(Arrays.toString(arr));
//使用for循环来把代码简化
for (int i = 1; i <arr.length ; i++) {
//实用逐步推到的方法来讲解,便于理解
//第一轮 {101,34,119,1}; =》 {34,101,119,1}
//定义待插入的数
int insertVal = arr[i];
//即arr[1]的前面这个数的下标
int insertIndex = i-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第"+i+"轮插入后");
System.out.println(Arrays.toString(arr));
}
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间"+deta2);
insertSort(arr);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
//这里我们判断下是否需要赋值
if (insertIndex +1 != i) {
arr[insertIndex + 1] = insertVal;
}
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class InsertSort {
public static void main(String[] args) {
//int [] arr = {101,34,119,1};
//测试一下冒泡的速度O(n^2),给八万个数据,测试
//创建要给80000个的随机数组
int[] arr =new int[8];
for (int i = 0; i < 8; i++) {
//生成一个[0,80000]数
arr[i] = (int)(Math.random()*80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间"+deta2);
insertSort(arr);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
System.out.println(Arrays.toString(arr));
}
/**
* 插入排序
*/
public static void insertSort(int[] arr){
//使用for循环来把代码简化
for (int i = 1; i <arr.length ; i++) {
//实用逐步推到的方法来讲解,便于理解
//第一轮 {101,34,119,1}; =》 {34,101,119,1}
//定义待插入的数
int insertVal = arr[i];
//即arr[1]的前面这个数的下标
int insertIndex = i-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
//这里我们判断下是否需要赋值
if (insertIndex +1 != i) {
arr[insertIndex + 1] = insertVal;
}
//System.out.println("第"+i+"轮插入后");
// System.out.println(Arrays.toString(arr));
}
/* //实用逐步推到的方法来讲解,便于理解
//第一轮 {101,34,119,1}; =》 {34,101,119,1}
//定义待插入的数
int insertVal = arr[1];
//即arr[1]的前面这个数的下标
int insertIndex = 1-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第一轮插入后");
System.out.println(Arrays.toString(arr));
//第二轮
//定义待插入的数
insertVal = arr[2];
//即arr[1]的前面这个数的下标
insertIndex = 2-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第二轮插入后");
System.out.println(Arrays.toString(arr));
//第三轮
//定义待插入的数
insertVal = arr[3];
//即arr[1]的前面这个数的下标
insertIndex = 3-1;
//给inserrtVal 找到插入的位置
//说明
//1.insertIndex >= 0 保证在给insertVal 找插入位置,不越界
//2.insertIndex < arr[insertIndex]待插入的数,还没有找到插入的位置
//3.就需要将arr[insertIndex] 后后移
while (insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex]; //arr [insertIndex]
insertIndex--;
}
//当退出while循环时,说明插入的位置找到,insertIndex + 1;
arr[insertIndex + 1] = insertVal;
System.out.println("第三轮插入后");
System.out.println(Arrays.toString(arr));*/
}
}
我们看简单的插入排序可能存在的问题
数组arr={
2,3,4,5,6,1},这是需要插入的数1(最小),这样的过程是:
{
2,3,4,5,6,6},
{
2,3,4,5,5,6},
{
2,3,4,4,5,6},
{
2,3,3,4,5,6},
{
2,2,3,4,5,6},
{
1,2,3,4,5,6}
结论:当需要插入的数是最小的数时,后移的次数明显增多,对效率有影响。
希尔排序是希尔于1959年提出的一种排序算法。希尔排序也是一种排序,它是简单插入排序经过改进之后的一个**更高效的版本**,也称为**缩小增量排序**
希尔排序是把记录按下标增量分组,对每组使用直接插入排序算法的排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1小时,整个文件被分成一组,算法便终止
有一群小牛,考试成绩分别是{
8,9,1,7,2,3,5,4,6,0}请从小到大排序,请分别使用
1. 希尔排序时,对有序排序的插入时采用交换法,并测试排序时速
2. 希尔排序时,有序序列插入时采用移动法,并测试排序速度
public class ShellSort {
public static void main(String[] args) {
int[] arr ={
8,9,1,7,2,3,5,4,6,0};
}
}
/**
* 使用逐步推到的方式来编写希尔排序
* 1. 希尔排序时,对有序排序的插入时采用交换法,并测试排序时速
* DuanXS
*/
public static void shellSort(int[] arr) {
int temp = 0;
//希尔排序的第一轮排序
//因为是第一轮排序,是将10个数据分成5组
for (int i = 5; i < arr.length; i++) {
//遍历各组中所有的元素(共5组,每组有2个元素),步长5
for (int j = i - 5; j >= 0; j -= 5) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 5]) {
temp = arr[j];
arr[j] = arr[j + 5];
arr[j + 5] = temp;
}
}
}
}
for (int i = 5; i < arr.length; i++) {
//遍历各组中所有的元素(共5组,每组有2个元素),步长5
for (int j = i - 5; j >= 0; j -= 5) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 5]) {
temp = arr[j];
arr[j] = arr[j + 5];
arr[j + 5] = temp;
}
}
}
System.out.println("希尔排序1轮后=" + Arrays.toString(arr));
}
public static void main(String[] args) {
int[] arr = {
8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
shellSort(arr);
}
//希尔排序的第2轮排序
//因为是第2轮排序,是将10个数据分成5/2=2组
for (int i = 2; i < arr.length; i++) {
//遍历各组中所有的元素(共2组,每组有2个元素),步长2
for (int j = i - 2; j >= 0; j -= 2) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 2]) {
temp = arr[j];
arr[j] = arr[j + 2];
arr[j + 2] = temp;
}
}
}
System.out.println("希尔排序2轮后=" + Arrays.toString(arr));
//希尔排序的第3轮排序
//因为是第3轮排序,是将10个数据分成2/2=1组
for (int i = 1; i < arr.length; i++) {
//遍历各组中所有的元素(共1组,每组有1个元素),步长1
for (int j = i - 1; j >= 0; j -= 1) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("希尔排序3轮后=" + Arrays.toString(arr));
int count = 0;
//根据前面的逐步分析,使用循环处理
for (int x = arr.length/2; x > 0; x/=2) {
//希尔排序的第x轮排序
//因为是第x轮排序,是将10个数据分成5/2=2组
for (int i = x; i < arr.length; i++) {
//遍历各组中所有的元素(共x组,每组有x/2个元素),步长x
for (int j = i - x; j >= 0; j -= x) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + x]) {
temp = arr[j];
arr[j] = arr[j + x];
arr[j + x] = temp;
}
}
}
System.out.println("希尔排序"+(++count)+"轮后=" + Arrays.toString(arr));
}
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
shellSort(arr);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
//System.out.println(Arrays.toString(arr));
}
/**
* 对交换方的排序进行优化-》移位法
*/
public static void shellSort2(int[] arr) {
//增量X,并逐步的缩小增量
for (int x = arr.length / 2; x > 0; x /= 2) {
//从第X个元素,逐个对其所在的组进行直接插入排序
for (int i = x; i < arr.length; i++) {
int j = i;
int temp = arr[j];
if (arr[j] < arr[j - x]) {
while (j - x >= 0 && temp < arr[j - x]) {
//移动
arr[j] = arr[j - x];
j -= x;
}
//当退出循环后,就给x找到了插入位置
arr[j] = temp;
}
}
}
}
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
shellSort(arr);//交换式
shellSort2(arr);//移位式
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间"+deta3);
//System.out.println(Arrays.toString(arr));
}
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class ShellSort {
public static void main(String[] args) {
//int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
shellSort(arr);//交换式
shellSort2(arr);//移位式
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
// System.out.println(Arrays.toString(arr));
}
/**
* 使用逐步推到的方式来编写希尔排序
* 1. 希尔排序时,对有序排序的插入时采用交换法,并测试排序时速
* 2. 希尔排序时,有序序列插入时采用移动法,并测试排序速度
* DuanXS
*/
public static void shellSort(int[] arr) {
int temp = 0;
int count = 0;
//根据前面的逐步分析,使用循环处理
for (int x = arr.length / 2; x > 0; x /= 2) {
//希尔排序的第x轮排序
//因为是第x轮排序,是将10个数据分成5/2=2组
for (int i = x; i < arr.length; i++) {
//遍历各组中所有的元素(共x组,每组有x/2个元素),步长x
for (int j = i - x; j >= 0; j -= x) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + x]) {
temp = arr[j];
arr[j] = arr[j + x];
arr[j + x] = temp;
}
}
}
// System.out.println("希尔排序" + (++count) + "轮后=" + Arrays.toString(arr));
}
/*
//希尔排序的第一轮排序
//因为是第一轮排序,是将10个数据分成5组
for (int i = 5; i < arr.length; i++) {
//遍历各组中所有的元素(共5组,每组有2个元素),步长5
for (int j = i - 5; j >= 0; j -= 5) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 5]) {
temp = arr[j];
arr[j] = arr[j + 5];
arr[j + 5] = temp;
}
}
}
System.out.println("希尔排序1轮后=" + Arrays.toString(arr));
//希尔排序的第2轮排序
//因为是第2轮排序,是将10个数据分成5/2=2组
for (int i = 2; i < arr.length; i++) {
//遍历各组中所有的元素(共2组,每组有2个元素),步长2
for (int j = i - 2; j >= 0; j -= 2) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 2]) {
temp = arr[j];
arr[j] = arr[j + 2];
arr[j + 2] = temp;
}
}
}
System.out.println("希尔排序2轮后=" + Arrays.toString(arr));
//希尔排序的第3轮排序
//因为是第3轮排序,是将10个数据分成2/2=1组
for (int i = 1; i < arr.length; i++) {
//遍历各组中所有的元素(共1组,每组有1个元素),步长1
for (int j = i - 1; j >= 0; j -= 1) {
//如果当前的元素大于加上步长后的哪个元素,说明交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("希尔排序3轮后=" + Arrays.toString(arr));
*/
}
/**
* 对交换方的排序进行优化-》移位法
*/
public static void shellSort2(int[] arr) {
//增量X,并逐步的缩小增量
for (int x = arr.length / 2; x > 0; x /= 2) {
//从第X个元素,逐个对其所在的组进行直接插入排序
for (int i = x; i < arr.length; i++) {
int j = i;
int temp = arr[j];
if (arr[j] < arr[j - x]) {
while (j - x >= 0 && temp < arr[j - x]) {
//移动
arr[j] = arr[j - x];
j -= x;
}
//当退出循环后,就给x找到了插入位置
arr[j] = temp;
}
}
}
}
}
package com.sort;
public class QuickSort {
public static void main(String[] args) {
int[] arr={
-9,78,0,23,-567,70};
}
}
public static void quickSort(int[] arr, int left, int right){
int l=left;//左下标
int r= right;//右下标
int pivot = arr[(left+right)/2];//取中间值
}
//while循环的目的是让比pivot 值小放再左边
//比pivot值大放到右边
while (l < r) {
}
//在pivot的左边一直找,找到大于等于pivot值,才退出
while (arr[l] < pivot) {
l += 1;
}
//在pivot的右边一直找,找到小于等于pivot值,才退出
while (arr[r] > pivot) {
r -= 1;
}
//如果 l>=r 说明pivot的左右两值,已经按照左边
// 全部是小于等于pivot值,右边全部大于等于pivot值
if (l >= r) {
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l]==pivot值 相等r--,前移
if (arr[l] == pivot) {
r -= 1;
}
//如果交换完后,发现这个arr[l]==pivot值 相等l++,后移
if (arr[r] == pivot) {
l += 1;
}
public static void main(String[] args) {
int[] arr = {
-9, 78, 0, 23, -567, 70};
quickSort(arr, 0, arr.length - 1);
System.out.println("arr=" + Arrays.toString(arr));
}
//递归
//如果l==r,必须l++,r--,否则为出现栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if (left < r) {
quickSort(arr, left, r);
}
//向右递归
if (right > l) {
quickSort(arr, l, right);
}
public static void main(String[] args) {
// int[] arr = {-9, 78, 0, 23, -567, 70};
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
quickSort(arr, 0, arr.length - 1);
// System.out.println("arr=" + Arrays.toString(arr));
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
}
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class QuickSort {
public static void main(String[] args) {
// int[] arr = {-9, 78, 0, 23, -567, 70};
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
quickSort(arr, 0, arr.length - 1);
// System.out.println("arr=" + Arrays.toString(arr));
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
}
public static void quickSort(int[] arr, int left, int right) {
int l = left;//左下标
int r = right;//右下标
int pivot = arr[(left + right) / 2];
int temp = 0;//临时变量,作为交换时使用
//while循环的目的是让比pivot 值小放再左边
//比pivot值大放到右边
while (l < r) {
//在pivot的左边一直找,找到大于等于pivot值,才退出
while (arr[l] < pivot) {
l += 1;
}
//在pivot的右边一直找,找到小于等于pivot值,才退出
while (arr[r] > pivot) {
r -= 1;
}
//如果 l>=r 说明pivot的左右两值,已经按照左边
// 全部是小于等于pivot值,右边全部大于等于pivot值
if (l >= r) {
break;
}
//交换
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l]==pivot值 相等r--,前移
if (arr[l] == pivot) {
r -= 1;
}
//如果交换完后,发现这个arr[l]==pivot值 相等l++,后移
if (arr[r] == pivot) {
l += 1;
}
}
//递归
//如果l==r,必须l++,r--,否则为出现栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if (left < r) {
quickSort(arr, left, r);
}
//向右递归
if (right > l) {
quickSort(arr, l, right);
}
}
}
package com.sort;
public class MergetSort {
public static void main(String[] args) {
int arr[] = {
8, 4, 5, 7, 1, 3, 6, 2};
}
}
/**
* 合并方法
* @param arr 排序的原始数组
* @param left 左边有序序列的初始所引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merget(int[] arr, int left, int mid, int right, int[] temp) {
}
/**
* 合并方法
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始所引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
* @param temp 做中转的数组
*/
public static void merget(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;//初始化i,左边有序序列的初始化索引
int j = mid + 1;//初始化j,右边有序序列的初始索引
int t = 0;//指向temp数组的当前索引
}
//第一步
//先把左右两边的(有序)数据按照规则填充到temp数组中
//直到左右两边的有序序列,有一边处理完毕为止
//第二步
//把所有剩余数据的一边的数据依次全部填充到temp
//第三步
//将temp数组的元素拷贝到arr
//第一步
//先把左右两边的(有序)数据按照规则填充到temp数组中
//直到左右两边的有序序列,有一边处理完毕为止
while (i <= mid && j <= right) {
//如果左边有序序列的当前元素小于等于右边有序序列的当前元素,
//即把左边的当前元素填充到temp数组里面去
//然后t++,i++ (后移)
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t += 1;
i += 1;
} else {
//反之,将右边有序序列的当前元素,填充到temp数组
temp[t] = arr[j];
t += 1;
j += 1;
}
}
//第二步
//把所有剩余数据的一边的数据依次全部填充到temp
while (i <= mid) {
//左边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[i];
t += 1;
i += 1;
}
while (j <= right) {
//右边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[j];
t += 1;
j += 1;
}
//第三步
//将temp数组的元素拷贝到arr
//注意,并不是每次都拷贝所有
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
//第一次tempLeft=0,rigth=1;
// 第二次tempLeft=2,rigth=3;
// 第三次tempLeft=0,rigth=3;
// 最后一次tempLeft=0,rigth=7;
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
/**
* 分+合方法
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始所引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void mergetSort(int[] arr, int left, int mid, int right, int[] temp){
}
public static void mergetSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2; //中间索引
}
public static void mergetSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2; //中间索引
//向左递归进行分解
mergetSort(arr, left, mid, temp);
}
}
if (left < right) {
int mid = (left + right) / 2; //中间索引
//向左递归进行分解
mergetSort(arr,left,mid,temp);
mergetSort(arr, left, mid, temp);
//向右递归进行分解
mergetSort(arr, mid + 1, right, temp);
}
}
public static void main(String[] args) {
int arr[] = {
8, 4, 5, 7, 1, 3, 6, 2};
int temp[] = new int[arr.length];//归并排序需要一个额外的空间
mergetSort(arr, 0, arr.length - 1, temp);
System.out.println("归并排序后="+ Arrays.toString(arr));
}
//向右递归进行分解
mergetSort(arr, mid + 1, right, temp);
//到合并
merget(arr, left, mid , right, temp);
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class MergetSort {
public static void main(String[] args) {
//int arr[] = {8, 4, 5, 7, 1, 3, 6, 2};
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
int temp[] = new int[arr.length];//归并排序需要一个额外的空间
mergetSort(arr, 0, arr.length - 1, temp);
// System.out.println("归并排序后=" + Arrays.toString(arr));
}
/*
* 分+合方法
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始所引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void mergetSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2; //中间索引
//向左递归进行分解
mergetSort(arr, left, mid, temp);
//向右递归进行分解
mergetSort(arr, mid + 1, right, temp);
//到合并
merget(arr, left, mid , right, temp);
}
}
/**
* 合并方法
*
* @param arr 排序的原始数组
* @param left 左边有序序列的初始所引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merget(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;//初始化i,左边有序序列的初始化索引
int j = mid + 1;//初始化j,右边有序序列的初始索引
int t = 0;//指向temp数组的当前索引
//第一步
//先把左右两边的(有序)数据按照规则填充到temp数组中
//直到左右两边的有序序列,有一边处理完毕为止
while (i <= mid && j <= right) {
//如果左边有序序列的当前元素小于等于右边有序序列的当前元素,
//即把左边的当前元素填充到temp数组里面去
//然后t++,i++ (后移)
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t += 1;
i += 1;
} else {
//反之,将右边有序序列的当前元素,填充到temp数组
temp[t] = arr[j];
t += 1;
j += 1;
}
}
//第二步
//把所有剩余数据的一边的数据依次全部填充到temp
while (i <= mid) {
//左边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[i];
t += 1;
i += 1;
}
while (j <= right) {
//右边的有序序列还有剩余的元素,就全部填充到temp
temp[t] = arr[j];
t += 1;
j += 1;
}
//第三步
//将temp数组的元素拷贝到arr
//注意,并不是每次都拷贝所有
t = 0;
int tempLeft = left;
while (tempLeft <= right) {
//第一次tempLeft=0,rigth=1;
// 第二次tempLeft=2,rigth=3;
// 第三次tempLeft=0,rigth=3;
// 最后一次tempLeft=0,rigth=7;
arr[tempLeft] = temp[t];
t += 1;
tempLeft += 1;
}
}
}
###基数排序——定义数组
package com.sort;
public class RadixSort {
public static void main(String[] args) {
int arr[] = {
53, 3, 542, 748, 14, 214};
}
}
/**
* 基数排序方法
*
* DuanXS
*/
public static void radixSort(int[] arr) {
}
}
//第一轮(针对每个元素的个位进行排序处理)
//第二轮(针对每个元素的十位进行排序处理)
//第三轮(针对每个元素的百位进行排序处理)
//定义一个二维数组,表示10个桶,每个桶就是一个一维数组
//说明
//1。二维数组包含10个一维数组
//2.为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
//3.明确,基数排序是使用空间的经典算法
int[][] bucket = new int[10][arr.length];
//为了记录每个桶中实际存放了多少个数据,我们定义一个一维数组来记录各个桶每次放入数据个数
//可以这么理解,bucktElementCounts[0],记录的就是bucket[0]桶的放入数据个数
int[] bucktElementCounts = new int[10];
//第一轮(针对每个元素的个位进行排序处理)
for (int j = 0; j < arr.length; j++) {
}
//取出每个元素的个位值
int digitOfElement = arr[j] % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
}
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index] = bucket[k][l];
arr[index++] = bucket[k][l];
}
}
}
System.out.println("第1轮,对应个位的排序处理arr="+ Arrays.toString(arr));
public class RadixSort {
public static void main(String[] args) {
int arr[] = {
53, 3, 542, 748, 14, 214};
radixSort(arr);
}
//第一轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
//第二轮(针对每个元素的十位进行排序处理)
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位值
int digitOfElement = arr[j] / 10 % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
}
System.out.println("第2轮,对应个位的排序处理arr=" + Arrays.toString(arr));
//第二轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
//第三轮(针对每个元素的百位进行排序处理)
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位值
int digitOfElement = arr[j] / 100 % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第3轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
System.out.println("第3轮,对应个位的排序处理arr=" + Arrays.toString(arr));
//根据前面的推到,我们可以得到最终的基数排序代码
//1.得到数组中最大的数的位数
int max = arr[0];//假设第一个数就是最大的数
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
//得到最大数是几位数
int maxLength = (max + "").length();
//这里我们使用循环将代码处理
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;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第i+1轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
System.out.println("第"+(i+1)+"轮,对应个位的排序处理arr=" + Arrays.toString(arr));
}
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
radixSort(arr);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
int temp[] = new int[arr.length];//基数排序需要一个额外的空间
// System.out.println("基数排序后=" + Arrays.toString(arr));
}
package com.sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class RadixSort {
public static void main(String[] args) {
// int arr[] = {53, 3, 542, 748, 14, 214};
//创建要给80000个的随机数组
int[] arr = new int[80000];
for (int i = 0; i < 80000; i++) {
//生成一个[0,80000]数
arr[i] = (int) (Math.random() * 80000);
}
System.out.println("排序前");
//测试排序前的时间
Date date2 = new Date();
//输出时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-mm-dd HH:mm:ss");
//有了这些我们可以拿到一个字符串
String deta2 = simpleDateFormat.format(date2);
System.out.println("排序前的时间" + deta2);
radixSort(arr);
Date date3 = new Date();
//有了这些我们可以拿到一个字符串
String deta3 = simpleDateFormat.format(date3);
System.out.println("排序后的时间" + deta3);
int temp[] = new int[arr.length];//基数排序需要一个额外的空间
// System.out.println("基数排序后=" + Arrays.toString(arr));
}
/**
* 基数排序方法
*
* DuanXS
*/
public static void radixSort(int[] arr) {
//根据前面的推到,我们可以得到最终的基数排序代码
//1.得到数组中最大的数的位数
int max = arr[0];//假设第一个数就是最大的数
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
//得到最大数是几位数
int maxLength = (max + "").length();
//第一轮(针对每个元素的个位进行排序处理)
//定义一个二维数组,表示10个桶,每个桶就是一个一维数组
//说明
//1。二维数组包含10个一维数组
//2.为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
//3.明确,基数排序是使用空间的经典算法
int[][] bucket = new int[10][arr.length];
//为了记录每个桶中实际存放了多少个数据,我们定义一个一维数组来记录各个桶每次放入数据个数
//可以这么理解,bucktElementCounts[0],记录的就是bucket[0]桶的放入数据个数
int[] bucktElementCounts = new int[10];
//这里我们使用循环将代码处理
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;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第i+1轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
// System.out.println("第"+(i+1)+"轮,对应个位的排序处理arr=" + Arrays.toString(arr));
}
/* //第一轮(针对每个元素的个位进行排序处理)
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位值
int digitOfElement = arr[j] % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第一轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
System.out.println("第1轮,对应个位的排序处理arr=" + Arrays.toString(arr));
//第二轮(针对每个元素的十位进行排序处理)
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位值
int digitOfElement = arr[j] / 10 % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第二轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
System.out.println("第2轮,对应个位的排序处理arr=" + Arrays.toString(arr));
//第三轮(针对每个元素的百位进行排序处理)
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个位值
int digitOfElement = arr[j] / 100 % 10;
//放入到对应的桶中
bucket[digitOfElement][bucktElementCounts[digitOfElement]] = arr[j];
bucktElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
index = 0;
//遍历每一个桶,并将桶中是数据,放入到原来数组
for (int k = 0; k < bucktElementCounts.length; k++) {
//如果桶中有数据,我们才放入到原数组中
if (bucktElementCounts[k] != 0) {
//循环该桶即第K个桶中(即将k个一维数组),放入
for (int l = 0; l < bucktElementCounts[k]; l++) {
//取出元素放到arr
arr[index++] = bucket[k][l];
}
}
//第3轮处理后,需要将每个bucktElementCounts[k]=0
bucktElementCounts[k] = 0;
}
System.out.println("第3轮,对应个位的排序处理arr=" + Arrays.toString(arr));
*/
}
}