1.直接插入排序
package edu.hue.ds.sort;
import java.util.Random;
/**
* @author dongtao
* @createTime 2021年08月02日 12:50:00
* @Description 直接插入排序
*
* 基本思想:
* 每步将一个待排序的对象,按其关键码大小,插入到前面已经排好序的一组对象的合适位置上,直到对象全部插入为止
* 即边插入边排序,保证子序列中随时都是排好序的
*/
public class DerectlyInsertSort {
public static void main(String args[]){
int[] arr = new int[100]; //定义一个数组
int length = 15; //定义元素个数
Random random = new Random();
for(int i = 1 ; i<=length; ++i){ //从下标1开始存储
arr[i] = random.nextInt(100);
}
System.out.print("排序前数组为:");
showArray(arr,length);
insertSort(arr,length);
System.out.println();
System.out.print("排序后数组为:");
showArray(arr,length);
}
public static void insertSort(int[] arr,int length){ //for循环遍历未排序数组元素,while进行条件判断遍历已排序数组并进行后续操作
//遍历未排序数组元素,将元素插入已排序数组中
for(int i = 1; i<=length; ++i){
arr[0] = arr[i];
int j = i-1; //初始化j指向已排序部分的最后一个元素,依次往前移动
while (j>0 && arr[j] > arr[0]){
arr[j+1] = arr[j]; //②arr[j]位置元素比带插入元素值大,将arr[j]元素放到arr[j+1]
j--; //别忘了
} //循环结束时,a[j]位置上的元素小于待插入元素,因此待插入元素要插入j+1这个位置
arr[j+1] = arr[0]; // ①找到arr[j]位置的元素比带插入元素值小,那么arr[j+1]就放入带插入元素
}
}
public static void showArray(int[] arr, int length){
for(int i = 1 ; i<=length; ++i){ //从下标1开始存储
System.out.print(arr[i]+" ");
}
}
}
2.冒泡排序
package edu.hue.ds.sort;
import java.util.Random;
/**
* @author dongtao
* @createTime 2021年08月18日 18:36:00
* @Description 冒泡排序
* 思路:
* 1、比较相邻的元素。如果第一个比第二个打,就交换他们两个;
* 2、针对每一对相邻元素作同样的操作,从开始第一对到结尾的最后一对。这步做完之后,最后的元素就是最大的数;
* 3、针对所有的元素重复以上的步骤,除了最后一个;
* 4、持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较。
*
* 每一躺比较都将数组中未排序部分的元素中最大元素,放到已排序部分的前面
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int[100]; //定义一个数组
int length = 15; //定义元素个数
Random random = new Random();
for(int i = 0 ; i<length; ++i){ //从下标1开始存储
arr[i] = random.nextInt(100);
}
System.out.print("排序前数组为:");
showArray(arr,length);
// bubbleSort(arr,length);
betterBubbleSort(arr,length);
System.out.println();
System.out.print("排序后数组为:");
showArray(arr,length);
}
public static void bubbleSort(int[] a,int length){
int i,j;
int temp =0;
for(i=0;i<length-1;++i){ //对第一个元素到倒数第二个元素进行操作
for(j=0;j<length-1-i;++j){ //注意,这里的j<length-1-i
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}
//排序算法的改进。就是如果有一趟排序过程操作完之后,并没有元素进行位置交换,那么说明数组中的元素已经是有序的了,那么就不需要再进行接下来的排序操作了
public static void betterBubbleSort(int[] a,int length){
int i,j;
int temp =0;
for(i=0;i<length-1;++i){ //对第一个元素到倒数第二个元素进行操作
boolean flag = true;
for(j=0;j<length-1-i;++j){ //注意,这里的j<length-1-i
if(a[j]>a[j+1]){
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
flag=false; //如果进行了元素位置的交换,就说明数组当前不是已经排好序的状态,仍是乱序
}
}
if(flag){
break;
}
}
}
public static void showArray(int[] arr, int length){
for(int i = 0 ; i<length; ++i){ //从下标1开始存储
System.out.print(arr[i]+" ");
}
}
}
3.希尔排序
基本思想:
先将整个待排记录序列分割成若干个子序列,分别进行直接插入排序,待整个序列中的记录都“基本有序”时,再对全体记录进行一次直接插入排序。
特点:
1、缩小增量
2、多遍插入排序
public static void shellSort1(int[] arr, int length) {
int temp;
//1、按照增量来遍历
for(int gap=length/2; gap>0; gap/=2){
//2、遍历未排序数组元素,从arr[gap]开始
for(int i = gap; i<length; ++i){
//将待排序元素值放入temp中
temp = arr[i];
int j;
//寻找待排序元素插入位置,并移动已排序元素
for(j=i; j>=gap && arr[j-gap] > temp ; j-=gap) //此处移动元素的条件要注意,从j=i开始
arr[j] = arr[j-gap];
arr[j] = temp; //结束移动之后,a[j]就是待插元素插入的位置
}
}
}
4.折半插入排序
package edu.hue.ds.sort;
import java.util.Random;
/**
* @author don-talk
* @createTime 2021年08月03日 12:51:00
* @Description 折半插入排序
*/
public class HalfInsertSort {
/*
* ①折半插入前提: 向已排好序数组中插入元素
*
* ②此处代码是在直接插入排序中,结合折半插入排序
* */
public static final int MAXSIZE = 100;
public static void main(String args[]){
//定义一个数组
int[] arr = new int[MAXSIZE];
//向数组中插入元素,从下标1开始存储,存入10个元素
int length = 10;
Random random = new Random();
for(int i=0; i<length; ++i){
arr[i] = random.nextInt(100); //随机生成0—100范围内的数字存入数组
}
System.out.println("排序前的数组为:");
showArray(arr,length);
// directlyInsert(arr,length);
binaryInsertSort(arr,length);
System.out.println();
System.out.println("排序后的数组为:");
showArray(arr,length);
}
public static void showArray(int[] arr, int length){
for(int i=0;i<length;++i){
System.out.print(arr[i]+" ");
}
}
public static void directlyInsert(int[] arr, int length){
for(int i=1;i<=length;++i){ //遍历未排序数组元素
//将已排序数组,和待插入元素放入折半插入排序方法中
//使用折半查找,获取插入元素位置
int place = halfInsertSort(arr,i-1,length,arr[i]);
}
}
public static int halfInsertSort(int[] arr, int r,int length, int item) {
int left,right;
left = 0;
right = r;
while (right >= left){
int mid = (left+right)/2;
if(arr[mid] > item){
right = mid-1;
}else if(arr[mid] < item){
left = mid+1;
}
}
return left+1;
}
public static void binaryInsertSort(int[] a,int length){
if(length<=1){ //当数组长度为1时,那就已经排好序了,直接返回
return;
}
int i,j,low,high,mid,temp;
for(i=1;i<length;++i){
low=0; //low和high的初始化必须放在for循环内部,因为low和high后面会改变不断改变
high=i-1;
temp=a[i];
while(high>=low){
mid=(low+high)/2;
if(a[mid]>=temp){
high=mid-1;
}else{
low=mid+1;
}
}//while循环结束时,high+1就是要插入的位置
for(j=i;j>high+1&&j>0;--j){
a[j]=a[j-1];
}
a[high+1]=temp;
}
}
}
5.快速排序
package edu.hue.ds.sort;
/**
* @author don-talk
* @createTime 2021年07月29日 12:54:00
* @Description 快速排序
*/
public class QuickSort {
public static void main(String args[]){
int[] arr = {543,32,65,8,5,10,987,999,57,75};
quickSort(arr,0,arr.length-1);
for(int i = 0; i<arr.length;++i){
System.out.print(arr[i]+" ");
}
}
public static void quickSort(int[] arr , int left, int right){
//如果左指针大于右指针,结束排序
if(left >= right){
return;
}
//①确定基准数
int base = arr[left];
int i = left;
int j = right;
//i和j不相遇的时候,在循环中检索
while(i!=j){
//先j移动,碰到比基准点小的元素时停止
while(arr[j] >= base && j>i ){
j--;
}//该while结束,说明右指针j已经遇到比准基数小的元素了
//再i移动,碰到比基准点大的元素时停止
while(arr[i] <= base && i<j){
i++;
}//该while结束,说明左指针也已经找到比准基数大的元素了
//交换i、j位置的元素
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}//该循环结束时,i和j相遇
//把基准数赋值到i和j相遇位置
arr[left] = arr[i];
arr[i] = base;
//左边快排
quickSort(arr,left,i-1);
//右边快排
quickSort(arr,j+1,right);
}
}