一、冒泡排序
/**
* @author QLBF
* @version 1.0
* @date 2021/4/10 15:30
*/
//冒泡排序
public class Maopao {
public static int[] paixu(int []array){
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - 1-i; j++) {
if (array[j]>array[j+1]){
int temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
return array;
}
public static void main(String[] args) {
int arr[]=new int[]{2,1,7,4,8,3,9,-1};
int[] afterarr = paixu(arr);
for (int i : afterarr) {
System.out.println(i);
}
}
}
二、简单选择排序
选择排序原理即是,遍历元素找到一个最小(或最大)的元素,把它放在第一个位置,然后再在剩余元素中找到最小(或最大)的元素,把它放在第二个位置,依次下去,完成排序。
/**
* @description: 简单选择排序
* @param: * @param: null
* @return:
* @author QLBF
* @date: 2021/4/11 17:09
*/
public class Xuanzhe {
public static int[] paixu(int []array){
for (int i = 0; i < array.length-1; i++) {
int minIndex=i;
for (int j = i+1; j < array.length; j++) {
if (array[j]<array[minIndex]){
minIndex=j;
}
}
if (i!=minIndex){
int temp=array[i];
array[i]=array[minIndex];
array[minIndex]=temp;
}
}
return array;
}
public static void main(String[] args) {
int array[]={3,2,9,4,85,44,33,1,10};
int[] paixu = paixu(array);
for (int i : paixu) {
System.out.println(i);
}
}
}
三、直接插入排序
原理说明:直接插入排序是一种最简单的插入排序方法,它的基本思想是,仅有一个元素的序列总是有序的,因此,对n 个记录的序列,可从第二个元素开始直到第n 个元素,逐个向有序序列中执行插入操作,从而得到n 个元素按关键字有序的序列。
/**
* @author QLBF
* @version 1.0
* @date 2021/4/13 16:11
*/
public class EightSort {
/**
* @description: 直接插入排序
* @param: * @param: null
* @return:
* @author QLBF
* @date: 2021/4/13 17:06
*/
public static int[] DirectInsertSort(int[] array){
System.out.print("进行直接插入排序后的数组:");
for (int i = 1; i < array.length; i++) {
int temp=array[i];
int j=i-1;
while (j>=0 && temp<array[j]){
array[j+1]=array[j];
j--;
}
//这里是j+1而不是j++
array[j+1]=temp;
}
return array;
}
public static void main(String[] args) {
int array[]=new int[]{4,2,5,1,8,7,9,3};
System.out.print("排序前数组:");
for (int i : array) {
System.out.print(i+" ");
}
System.out.println();
int[] arrayafter = DirectInsertSort(array);
for (int i : arrayafter) {
System.out.print(i+" ");
}
}
}
四、折半插入排序
原理说明:折半插入排序是在直接插入排序的基础上,不断对半二分有序序列来寻找插入位置,即搜索插入位置的方法可以使用折半查找实现,是对直接插入排序的一种改进。
五、希尔排序
- 参考
先分组,再排序,gap=2,意思是把隔2个的元素组成一组,再运用插入排序的意思。
package com.yuan;
/**
* @author QLBF
* @version 1.0
* @date 2021/5/22 16:13
*/
public class demo1 {
public static void shellSort(int[] array){
for (int gap = array.length/2; gap > 0; gap=gap/2) {
for (int i = gap; i < array.length; i++) {
for (int j = i-gap; j >=0 ; j=j-gap) {
if (array[j]>=array[j+gap]){
int temp=array[j];
array[j]=array[j+gap];
array[j+gap]=temp;
}
}
}
}
}
public static void main(String[] args) {
int []array=new int[]{9,-2,4,3,4};
shellSort(array);
for (int i : array) {
System.out.print(" "+i);
}
}
}
六、快速排序
参考:https://blog.csdn.net/qq_26122557/article/details/79458649
public class e8 {
/**
* @description: 快速排序
* @param: * @param: null
* @return:
* @author QLBF
* @date: 2021/4/20 18:59
*/
public static void QuickSort(int[] array,int low,int high){
int i=low;
int j=high;
//temp就是基准位
if (low>high){
return ;
}
//这个temp要在上面判断下,否则出错(又可能越界的)
int temp=array[low];
//这里用while而不用if
while (i<j){
//先从最右往左查小的,&&i<j条件不可少,=必须加的
while (temp<=array[j] &&i<j){
j--;
}
//再从最左往右查大的
while (temp>=array[i]&&i<j){
i++;
}
//如果它们都找到了大和小它们没相遇,则交换它们哨兵对应的值
if (i<j){
int temp2=array[i];
array[i]=array[j];
array[j]=temp2;
}
}
//当它们相遇了则交换它们相遇的值和基准位
array[low]=array[i];
array[i]=temp;
//递归调用左右半数组,注意取j还是high哦
QuickSort(array,low,j-1);
QuickSort(array,j+1,high);
}
public static void main(String[] args) {
int array[]=new int[]{4,2,5,1,8,7,9,3};
System.out.print("排序前数组:");
for (int i : array) {
System.out.print(i+" ");
}
System.out.println();
QuickSort(array,0,array.length-1);
System.out.print("经过快速排序后的数组:");
for (int i : array) {
System.out.print(i+" ");
}
}
}
七、归并排序
(分+合)
package com.yuan;
/**
* @author QLBF
* @version 1.0
* @date 2021/5/23 17:13
*/
public class demo2 {
//分+合
public static void mergeSort(int[] array,int left,int right,int[] temp){
if (left<right){
int mid=(left+right)/2;
//这里的mergeSort会把某两半变得有序(一直拆为1个),再进行merge的合并
mergeSort(array,left,mid,temp);
mergeSort(array,mid+1,right,temp);
merge(array,left,right,mid,temp);
}
}
//合
public static void merge(int[] array,int left,int right,int mid,int[] temp){
int i=left;
int j=mid+1;
int t=0;
while (i<=mid && j<=right){
if (array[i]<=array[j]){
temp[t]=array[i];
i++;
t++;
}else {
temp[t]=array[j];
j++;
t++;
}
}
//这里记得要写=
while (i<=mid){
temp[t]=array[i];
i++;
t++;
}
while (j<=right){
temp[t]=array[j];
j++;
t++;
}
//赋值给这个数组
t=0;
int templeft=left;
while (templeft<=right){
array[templeft]=temp[t];
t++;
templeft++;
}
}
public static void main(String[] args) {
int []array=new int[]{9,-2,5,4};
int[] temp=new int[array.length];
mergeSort(array,0,array.length-1,temp);
for (int i : array) {
System.out.print(" "+i);
}
}
}
八、堆排序
参考王道考研视频
1.先构建大根堆或者小根堆(i从1开始)
9那里
这里的左右孩子2i等还是得看你的具体的i从0开始还是从1开始。
若i从0开始,那么它的左孩子是2i+1,右孩子是2i+2
好好把53下坠过程演示一遍就理解下面的代码了:
2.基于1构建的大根堆或者小根堆进行排序:
每次换完堆顶元素和末尾元素,都要再次进行构建大根堆或者小根堆(就是1的过程)
排序代码:
代码如下(由于i从0开始,所以代码和上述代码有点出入,但是思想是一样的):
package com.yuan.demo8;
/**
* @author QLBF 堆排序
* @version 1.0
* @date 2021/6/11 11:20
*/
public class test8 {
//1.建立大根堆
public static void bulidMaxHeap(int[] array,int len){
//i从 非叶子结点开始,i=array.len/2开始,i从0开始,所以还要-1
for (int i = len/2-1; i >= 0; i--) {
headAdjust(array,i,len);
}
}
//2.(重点)将以k为根的子树调整为大根堆,len为要调整的长度,每次长度都不一样的(一开始构建大根堆是一样的)
private static void headAdjust(int[] array, int k, int len) {
int temp=array[k]; //temp暂存子树的跟结点
//不断下坠的过程,由于i从0开始,所以这里2i+1才是左子树
for (int i = 2*k+1; i < len ; i=i*2+1) {//沿值较大的子节点向下筛选
//i<len-1 必不可少,判断有无右孩子的作业(i=len-1证明无有孩子了,因为这里i=2i+1,你要i=2i+2=len才有右孩子)
if (i<len-1 && array[i] <array[i+1]){
//就要指针指向左右子树中较大的一个
i++;
}
//这是if而不是else if
//这里是temp比较而不能用array[k]来比较
if (temp>=array[i]){
//就是当前结点比左右孩子都大,跳出
break;
}else {
//否则把较大的孩子与当前孩子互换
array[k]=array[i];
k=i;
}
}
array[k]=temp; //确定好最终下坠的位置,就把它原本的值还给它
}
//3.真正的堆排序完整逻辑
//len传入不用-1,因为i从0开始
public static void headSort(int[] array,int len){
bulidMaxHeap(array,len); //调用1 初始建堆
/* n-1趟交换和建堆过程,每次堆顶元素和末尾元素交换完,
都得以末尾元素(此时在堆顶)重新构建一次堆*/
for (int i = len-1; i > 0; i--) {
//堆顶元素和末尾元素交换
int temp=array[i];
//这是把堆顶元素(最大值)赋值给数组的最后一个值(从此i末尾往前就是有序了)
array[i]=array[0];
array[0]=temp;
headAdjust(array,0,i);//把剩余的待排序元素重新构建堆(最后一个已经是有序的,所以不用i+1了哦),这里的i为代构建堆的长度,不要和前面的i搞混了
}
}
public static void main(String[] args) {
int[] array=new int[]{8,-2,3,1,7,5,11,-3,4};
headSort(array,array.length);
for (int i : array) {
System.out.println(i+" ");
}
}
}
可参考:堆排序
九、基数排序
下面演示递减
第一趟收集是从个位数大(因为我们要的是递减排序)的开始弄成一个链表,而且要队头放在前面
https://blog.csdn.net/weixin_44531966/article/details/116464294
六个排序