插入排序
package sort;
import java.util.Arrays;
public class insertsort {
public static void main(String[] args) {
int[] arr = {100,34,119,1,22,98};
insertsort(arr);
System.out.println(Arrays.toString(arr));
}
public static void insertsort(int[] arr){
//使用逐步推到的方式
//第一轮:int[] arr = {100,34,119,1,22,98};
//定义待插入的数
/*int insertVal = arr[1];
int insertIndex = 1-1;//前一个数的下标
//给insertVal插入一个位置
//insertIndex < arr[insertIndex] 说明待插入的数还没有找到位置
while(insertIndex >= 0 && insertVal < arr[insertIndex]){//为了保证不越界
arr[insertIndex +1] = arr[insertIndex];
insertIndex --;
}
//当退出while循环时,说明插入的位置找到,insertIndex +1;
arr[insertIndex + 1] = insertVal;
System.out.println(Arrays.toString(arr));
//第二轮
insertVal = arr[2];
insertIndex = 2-1;//前一个数的下标
while(insertIndex >= 0 && insertVal < arr[insertIndex]){//为了保证不越界
arr[insertIndex +1] = arr[insertIndex];
insertIndex --;
}
arr[insertIndex + 1] = insertVal;
System.out.println(Arrays.toString(arr));*/
for (int i = 1 ; i< arr.length ;i++){
int insertVal = arr[i];
int insertIndex = i-1;
while(insertIndex >= 0 && insertVal < arr[insertIndex]){
arr[insertIndex + 1] = arr[insertIndex];
insertIndex --;
}
arr[insertIndex +1 ] = insertVal;
System.out.println("第" + i + "次交换:" + Arrays.toString(arr));
}
}
}
选择排序
package sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.text.SimpleDateFormat;
public class sort {
//选择排序算法
public static void main(String[] args) {
int[] arr = {100,34,119,1,22,98};
selectsort(arr);
System.out.println(Arrays.toString(arr));
// int[] arr = new int[80000];
// for (int i = 0; i < 80000;i++){
// arr[i] = (int)(Math.random() * 80000);
// }
// Date date1 = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String s1 = simpleDateFormat.format(date1);
// System.out.println("排序前:" + s1);
// selectsort(arr);
// Date date2 = new Date();
// String s2 = simpleDateFormat.format(date2);
// System.out.println("排序后:" + s2);
}
//选择排序
public static void selectsort(int[] arr){
//使用逐步推导的方式来,讲解选择排序
for (int i =0; i<arr.length - 1; i++){
int minIndex= i;//假定最小数的索引
int min = arr[minIndex];//假定最小数的值
for ( int j = i+1 ; j<arr.length;j++){
if(min > arr[j]){//说明这个最小值并不是最小
min = arr[j];
minIndex = j;
}
}
//交换
//多一个判断条件
if(minIndex != i){
arr[minIndex] = arr[i];
arr[i] = min;
}
//System.out.println(Arrays.toString(arr));
}
}
}
快速排序
package sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class qiucksort {
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));
//测试快排的执行速度
//创建要给80000个的随机的数据
// int[] arr = new int[80000];
// for (int i = 0; i < arr.length; i++) {
// arr[i] = (int) (Math.random() * 80000);
// }
// Date datal = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// String date1Str = simpleDateFormat.format(datal);
// System.out.println("排序前的时间是=" + date1Str);
// quickSort(arr,0,arr.length-1);
// Date data2 = new Date();
// String date2Str = simpleDateFormat.format(data2);
// System.out.println("排序前的时间是=" + date2Str);
}
public static void quickSort(int[] arr, int left, int right) {
int l = left;//左下标
int r = right;//右下标
//pivot 中轴值
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[r] == 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 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};
radixsort(arr);
System.out.println(Arrays.toString(arr));
// int[] arr = new int[800000];
// int[] temp = new int[arr.length];
// for (int i = 0; i < 800000;i++){
// arr[i] = (int)(Math.random() * 800000);
// }
// Date date1 = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSS");
// String s1 = simpleDateFormat.format(date1);
// System.out.println("排序前:" + s1);
// radixsort(arr);
// Date date2 = new Date();
// String s2 = simpleDateFormat.format(date2);
// System.out.println("排序后:" + s2);
}
public static void radixsort(int[] arr){
//第一轮排序(针对个位进行处理)
//定义一个二维数组代表10个桶,每一个桶就是一个一维数组
int[][] bucket = new int[10][arr.length];
//为了记录每一个桶中实际存放了多少个数据,我们定义一个一维数组来记录各个桶每次放入的数据个数
int[] bucketElementCounts = new int[10];//记录每个桶中数据的数量
int max = arr[0];
for(int i = 0; i<arr.length;i++){
if (arr[i]>max){
max = arr[i];
}
}
//System.out.println("Max为" + max);
int maxLength = (max + "").length();//转换为字符串
int n =1;
for (int i = 0;i<maxLength;i++) {
for (int j = 0; j < arr.length; j++) {
//取出每个元素的个/十/百位
int digitOfElement = arr[j] / n % 10;
//放入到对应的桶中
//数组中的第一个数代表这0.1.2...
//数组中第二个数代表每一个桶中有多少个数
//bucketElementCounts[digitOfElement] 代表着每一个桶中,元素的索引
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
arr[index] = bucket[k][l];
index++;
}
}
bucketElementCounts[k] =0;//处理完一个桶之后需要将桶置为0
}
n *= 10;
//System.out.println(Arrays.toString(arr));
}
}
}
希尔排序交换法
package sort;
import java.util.Arrays;
public class shellsort {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellsort(arr);
// System.out.println(Arrays.toString(arr));
}
public static void shellsort(int [] arr){
//使用 逐步推导的方式编写希尔排序
//第一轮:希尔排序的第一轮排序
/*for (int i = 5; i < arr.length;i++){
//遍历各组中所有的元素(共5组,每组一共2个元素)
for(int j = i-5; j >=0; j-=5){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+5]){
int temp = arr[j];
arr[j] = arr[j+5];
arr[j+5] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
for (int i = 2; i < arr.length;i++){
//遍历各组中所有的元素(共2组,每组一共5个元素)
for(int j = i-2; j >=0; j-=2){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+2]){
int temp = arr[j];
arr[j] = arr[j+2];
arr[j+2] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
for (int i = 1; i < arr.length;i++){
//遍历各组中所有的元素(共1组,每组一共10个元素)
for(int j = i-1; j >=0; j-=1){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));*/
for (int gap = arr.length/2; gap > 0; gap /= 2){//确定每一次的步长
for (int i = gap;i < arr.length; i++){
for (int j = i-gap; j>= 0; j-= gap){
if (arr[j] > arr[j+gap]){
int temp = arr[j];
arr[j] = arr[j+gap];
arr[j+gap] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
}
希尔排序
package sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.text.SimpleDateFormat;
public class shellsort02 {
public static void main(String[] args) {
int[] arr = {8,9,1,7,2,3,5,4,6,0};
shellsort(arr);
System.out.println(Arrays.toString(arr));
// int[] arr = new int[80000];
// for (int i = 0; i < 80000;i++){
// arr[i] = (int)(Math.random() * 80000);
// }
// Date date1 = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSS");
// String s1 = simpleDateFormat.format(date1);
// System.out.println("排序前:" + s1);
// shellsort(arr);
// Date date2 = new Date();
// String s2 = simpleDateFormat.format(date2);
// System.out.println("排序后:" + s2);
}
/*public static void shellsort(int [] arr){
//使用 逐步推导的方式编写希尔排序
//第一轮:希尔排序的第一轮排序
*//*for (int i = 5; i < arr.length;i++){
//遍历各组中所有的元素(共5组,每组一共2个元素)
for(int j = i-5; j >=0; j-=5){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+5]){
int temp = arr[j];
arr[j] = arr[j+5];
arr[j+5] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
for (int i = 2; i < arr.length;i++){
//遍历各组中所有的元素(共2组,每组一共5个元素)
for(int j = i-2; j >=0; j-=2){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+2]){
int temp = arr[j];
arr[j] = arr[j+2];
arr[j+2] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
for (int i = 1; i < arr.length;i++){
//遍历各组中所有的元素(共1组,每组一共10个元素)
for(int j = i-1; j >=0; j-=1){
//如果当前元素大于加上步长后的的元素,说明交换
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));*//*
for (int gap = arr.length/2; gap > 0; gap /= 2){//确定每一次的步长
for (int i = gap;i < arr.length; i++){
for (int j = i-gap; j>= 0; j-= gap){
if (arr[j] > arr[j+gap]){
int temp = arr[j];
arr[j] = arr[j+gap];
arr[j+gap] = temp;
}
}
}
// System.out.println(Arrays.toString(arr));
}*/
public static void shellsort(int[] arr){
for (int gap = arr.length/2; gap > 0; gap /= 2){//确定每一次的步长
//从第gap个元素,逐个对其所在的组进行直接插入排序
for (int i = gap; i<arr.length;i++){
int j = i;
int temp = arr[j];
if (arr[j] < arr[j-gap]){
while( j- gap >=0 && temp < arr[j-gap]){
//移动
arr[j] = arr[j-gap];
j -= gap;
}
//退出循环,找到位置
arr[j] = temp;
}
}
// System.out.println(Arrays.toString(arr));
}
}
}
归并排序
package sort;
import java.text.SimpleDateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
public class merge {
static int count = 0;
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));
System.out.println(count);
// int[] arr = new int[800000];
// int[] temp = new int[arr.length];
// for (int i = 0; i < 800000;i++){
// arr[i] = (int)(Math.random() * 800000);
// }
// Date date1 = new Date();
// SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSS");
// String s1 = simpleDateFormat.format(date1);
// System.out.println("排序前:" + s1);
// mergesort(arr,0, arr.length-1,temp);
// Date date2 = new Date();
// String s2 = simpleDateFormat.format(date2);
// System.out.println("排序后:" + s2);
}
public static void mergesort(int[] arr,int left,int right,int[] temp) {
if(left<right){
int mid = (left + right) /2;
//向左递归进行分解
mergesort(arr,left,mid,temp);
//向右递归分解
mergesort(arr,mid+1,right,temp);
//每分解一次就合并一次
merge(arr,left,mid,right,temp);
}
}
//合并的方法
/**
*
* @param arr 原始数组
* @param left 左边序列的初始索引
* @param mid 中间索引
* @param right 右边索引
* @param temp 做中转的数组
*/
public static void merge(int[] arr ,int left , int mid,int right,int[] temp){
int i = left;//初始化i,左边有序序列的初始索引
int j = mid +1;//初始化j,右边有序序列的初始索引
int index = 0; //中间数组的索引
count ++;
//先把左右两边的数据,按规则拷贝到temp中
//直到左右两边有一侧处理完毕为止
while( i <= mid && j <= right){
if(arr[i] <= arr[j]){
temp[index] = arr[i];
index ++;
i ++;
} else {
temp[index] = arr[j];
index ++;
j ++;
}
}
//把有剩余数据的一边,剩余的数据一次放入temp中
while(i <= mid){
temp[index] = arr[i];
index ++;
i ++;
}
while( j <= right){
temp[index] = arr[j];
index ++;
j++;
}
//将temp数组中的原数放入temp中
index = 0; //将索引置0
int tempLeft = left;
while(tempLeft <= right){
arr[tempLeft] = temp[index];
index ++;
tempLeft ++;
}
}
}
堆排序
package sort;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.text.SimpleDateFormat;
public class bumpsort {
public static void main(String[] args) {
//要求将数组进行升序排序
//int arr[] = {4, 6, 8, 5, 9};
// 创建要给80000个的随机的数组
int[] arr = new int[8000000];
for (int i = 0; i < 8000000; i++) {
arr[i] = (int) (Math.random() * 8000000); // 生成一个[0, 8000000) 数
}
System.out.println("排序前");
Date data1 = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date1Str = simpleDateFormat.format(data1);
System.out.println("排序前的时间是=" + date1Str);
heapSort(arr);
Date data2 = new Date();
String date2Str = simpleDateFormat.format(data2);
System.out.println("排序前的时间是=" + date2Str);
//System.out.println("排序后=" + Arrays.toString(arr));
}
//编写一个堆排序的方法
public static void heapSort(int arr[]) {
int temp = 0;
System.out.println("堆排序!!");
// //分步完成
// adjustHeap(arr, 1, arr.length);
// System.out.println("第一次" + Arrays.toString(arr)); // 4, 9, 8, 5, 6
//
// adjustHeap(arr, 0, arr.length);
// System.out.println("第2次" + Arrays.toString(arr)); // 9,6,8,5,4
//完成我们最终代码
//将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
for(int i = arr.length / 2 -1; i >=0; i--) {
adjustHeap(arr, i, arr.length);
}
/*
* 2).将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
3).重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
*/
for(int j = arr.length-1;j >0; j--) {
//交换
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
adjustHeap(arr, 0, j);
}
// System.out.println("数组=" + Arrays.toString(arr));
}
//将一个数组(二叉树), 调整成一个大顶堆
/**
* 功能: 完成 将 以 i 对应的非叶子结点的树调整成大
* 顶堆
* 举例 int arr[] = {4, 6, 8, 5, 9}; => i = 1 => adjustHeap => 得到 {4, 9, 8, 5, 6}
* 如果我们再次调用 adjustHeap 传入的是 i = 0 => 得到 {4, 9, 8, 5, 6} => {9,6,8,5, 4}
* @param arr 待调整的数组
* @param i 表示非叶子结点在数组中索引
* @param lenght 表示对多少个元素继续调整, length 是在逐渐的减少
*/
public static void adjustHeap(int arr[], int i, int lenght) {
int temp = arr[i];//先取出当前元素的值,保存在临时变量
//开始调整
//说明
//1. k = i * 2 + 1 k 是 i结点的左子结点
for(int k = i * 2 + 1; k < lenght ; k = k * 2 + 1) {
if(k+1 < lenght && arr[k] < arr[k+1]) { //说明左子结点的值小于右子结点的值
k++; // k 指向右子结点
}
if(arr[k] > temp) { //如果子结点大于父结点
arr[i] = arr[k]; //把较大的值赋给当前结点
i = k; //!!! i 指向 k,继续循环比较
} else {
break;//!
}
}
//当for 循环结束后,我们已经将以i 为父结点的树的最大值,放在了 最顶(局部)
arr[i] = temp;//将temp值放到调整后的位置
}
}