public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){//递归跳出条件
return;
}
i=low;//左边第一个数字
j=high;//右边第一个数字
//temp就是基准位,也叫做中心位置我们一般把他设置在第一个
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//最后一次i++或者j--跳出循环后,如果满足条件则让数组中两个位置的数字交换
if (i<j) {//此时i=j则表示分组结束
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//在上面的分组结束之后,此时左边的数字都比基准小,右边的都比基准大
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
//这里是七种常见排序算法:
package com.itheima;
/**
* @author 32338
* @date 2024-06-26 00:10:05
* @description
*/
public class QuickSort {
/**
* @description
***:快速排序-递归
**/
public static void quickSort(int[] arr ,int low,int high){
//确定递归退出条件
if (low>high) {
return;
}
int i,j,temp,t;
i = low;
j = high;
temp = arr[low];
while (i<j){
while (i<j&&temp<=arr[j]){j--;}
while (i<j&&temp>=arr[i]){i++;}
if (i<j){
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
arr[low] = arr[i];
arr[i] = temp;
quickSort(arr,low,j-1);
quickSort(arr,j+1,high);
}
/**
* @description
***:插入排序
**/
public static void insertSort(int[] array){
//通过bound划分出两个区间
//[0,bound)表示已排序区间
//[bound,size )为待排序区间
for (int bound = 1; bound < array.length ; bound++) {//默认0号位置已将是排序得了,从1开始
int v = array[bound];//取出bound位置元素往前插
int cur = bound-1; //从bound-1的位置开始找位置,
for(;cur >= 0; cur--){
if(array[cur] > v){ //注意如果这个条件写成>=依旧可以完成排序,但是不为稳定排序了
array[cur+1] = array[cur];
}else {
break;//找到了合适的位置
}
}
//此时的cur+1位置即要插入的位置
array[cur+1] = v;
}
}
/**
* @description
***:希尔排序
**/
public static void shellSort(int[] array){
int gap = array.length/2;
while(gap > 1){
//需要循环进行分组插排
shellSortGap(array,gap);
gap/=2;
}
shellSortGap(array,1); //当gap为1时再进行一次插排
}
public static void shellSortGap(int[] array,int gap){
//通过bound划分出两个区间
//[0,bound)表示已排序区间
//[bound,size )为待排序区间
for (int bound = gap; bound < array.length ; bound++) {//默认0号位置已将是排序得了,从1开始
int v = array[bound];//取出bound位置元素往前插
int cur = bound-gap; //从bound-1的位置开始找位置, //找到同组中的上一个元素
for(;cur >= 0; cur -= gap){
if(array[cur] > v){ //注意如果这个条件写成>=依旧可以完成排序,但是不为稳定排序了
array[cur+gap] = array[cur];
}else {
break;//找到了合适的位置
}
}
//此时的cur+1位置即要插入的位置
array[cur+gap] = v;
}
}
/**
* @description
***:选择排序
**/
public static void selectSort(int[] array){
for (int bound = 0; bound < array.length-1 ; bound++) {
//[0,bound)为已排序区间bound位置元素为擂主,循环取出待排序区间元素与擂主比较
//如果小就交换(即打擂成功)
for(int cur = bound+1;cur < array.length;cur++){
if(array[bound] > array[cur]){ //打擂成功
int temp = array[bound];
array[bound] = array[cur];
array[cur] = temp;
}
}
}
}
/**
* @description
***:堆排序
**/
public static void heapSort(int[] array){
//先建大堆
CreatHeap(array);
//循环把堆顶元素交换到最后,并调整堆
for (int i = 0; i < array.length-1; i++) {
//当堆中只剩一个元素,也不需要进行调整,本来就是有序的
swap(array,0,array.length-1-i); //堆中元素个数为length-i,所以最后一个元素下标为length-i-1
//交换完之后把最后一个元素删掉
//堆的长度又进一步缩水了
//数组中
//[0,array.length-i-1)为待排序区间
//[array.length-i-1,array.length)为已排序区间
shiftDown(array,array.length-i-1,0);
}
}
public static void CreatHeap(int[] array) {
//从最后一个非叶子节点出发向前循环,依次进行向下调整
for(int i = (array.length-1-1)/2;i >=0;i--){
shiftDown(array,array.length,i);
}
}
public static void shiftDown(int[] array, int heapLength, int index) {
int parent = index;
int child = index*2 +1;
while(child <heapLength){
if(child+1 < heapLength && array[child+1] > array[child]){
child = child +1;
}
//条件结束,child已经指向左右子树中较大的数
if(array[child] > array[parent]){
swap(array,child,parent);
}
parent = child;
child = parent*2+1;
}
}
public static void swap(int[] array,int i, int j){
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
/**
* @description
***:冒泡排序
**/
public static void bubbleSort(int[] array){
//从前往后找最小的方式进行排序
//[0,bound)为已排序区间
//[bound,size)为待排序区间
for(int bound = 0 ; bound < array.length;bound++){
for(int cur = array.length-1;cur > bound; cur--){
if(array[cur-1] > array[cur]){
swap(array,cur-1,cur);
}
}
}
}
/**
* @description
***:归并排序
**/
//[low,mid) 有序区间
//[mid,high) 有序区间
//把这两个区间合并为一个有序区间
public static void merge(int[] array,int low,int mid,int high){
int[] output = new int[high-low]; //额外空间用来临时存放数据
int outputIndex = 0;//用来记录output中被放入了多少个元素
int cur1 = low;
int cur2 = mid;
while(cur1 < mid && cur2 < high ){
if(array[cur1] <= array[cur2]){
output[outputIndex] = array[cur1];
outputIndex++;
cur1++;
} else{
output[outputIndex] = array[cur2];
outputIndex++;
cur2++;
}
}
//循环结束肯定是cur1和cur2有一个先到达末尾
//把剩下的元素一股脑拷贝到output中
while(cur1 < mid){
output[outputIndex] = array[cur1];
outputIndex++;
cur1++;
}
while(cur2 < high){
output[outputIndex] = array[cur2];
outputIndex++;
cur2++;
}
//把output中的元素搬运回array中
for (int i = 0; i < high-low; i++) {
array[low+i] = output[i];
}
}
public static void mergeSort(int[] array){
mergeSortHelper(array,0,array.length);
}
//[low,high)为左闭右开区间.两者差值小于等于1,区间中就只有一个或两个元素
private static void mergeSortHelper(int[] array, int low, int high) {
if(high-low <= 1){
return;
}
int mid = (low + high)/2;
//这个方法执行完就认为low
mergeSortHelper(array,low,mid);
mergeSortHelper(array,mid,high);
//当左右区间归并排序完了,说明左右区间已经是有序区间了
//接下来就可以针对两个有序区间合并
merge(array,low,mid,high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}