冒泡排序,选择排序,插入排序,归并排序,快速排序,堆排序,

这里分别用程序来实现这些常见的排序,唉,还是菜,手撕要是写不出来就尴尬了

首先一张图来看看都有哪些排序并分析它们

来自常见的排序算法有哪些?如何实现这些算法?,可以去看看,里面用动态图介绍了几种排序的逻辑,我这主要是程序为主,关于理念概念什么的可以自行百度了

在这里插入图片描述

1、冒泡排序

通过相邻的两个数进行比较大小,大的换到后面,小的换到前面,这样一轮下来数组中最大的数就被放在了数组的最后一个,
第二轮确定数组中第二大的放在了数组倒数第二的位置

public class Main {
		public static void main(String[] args) {
			//输入测试用例
			int [] num = new int [] {5,4,7,8,9,5,1,3};
			//进行冒泡排序
			for(int i = 0; i < num.length-1; i++) { //总共需要多少轮
				for(int j = 0;j < num.length-1-i; j++) { //每一轮需要比较几次,这个次数应该是递减的
					if(num[j] > num[j+1]) {	//前面的比后面的大,它俩位置交换
						int index = num[j+1];
						num[j+1] = num[j];
						num[j] = index;
					}
				}
			}
			//输出排序后的结果
			for(int i =0;i< num.length;i++) {
				System.out.print(num[i]+" ");
			}
		}
}

在这里插入图片描述

选择排序

选择排序由两种,一种从最大的开始排,一种是从最小的开始排,这里演示选择最小的开始排序,原理是一样的,
只是一个是先遍历找到最大的放在最后面:最里面的for循环是从length-1-i到0
而另一个是先遍历找到最小的放在最前面:最里面的for循环是从i+1到length-1

public class Main {
	public static void main(String[] args) {
		//输入测试用例
		int [] num = new int [] {5,4,7,8,9,5,1,3};
		//选择排序(选最小的)
		int minIndex;
		for(int i =0; i< num.length-1; i++) { //遍历的轮数是一定的
			minIndex = i;
			for(int j =i+1;j< num.length;j++) { //每次比较的次数也是递减的
				if(num[minIndex] > num[j]) {
					minIndex = j;
				}
			}
			int indexNum = num[minIndex];
			num[minIndex] = num[i];
			num[i] = indexNum;
			
		}
		//输出排序后的结果
		for(int i =0;i< num.length;i++) {
			System.out.print(num[i]+" ");
		}
	}
}

在这里插入图片描述

3、插入排序

遍历数组,到哪个位置就从那个位置开始往前遍历,只要比前面的小就继续往前遍历,直到第一个还比它大就让第一个即往后的挪一个位置,或则前面那个比它小或者等于就可以不用往前遍历,插进此位置的后面一个位置,原来的就往后挪一个位置

public class Main {
	public static void main(String[] args) {
		//输入测试用例
		int [] num = new int [] {5,4,7,8,9,5,1,3};
		//插入排序
		int index;
		for(int i =0; i< num.length; i++) { //遍历的轮数是一定的
			//找到前面比当前数值小的位置索引
			index = i;
			for(int j = i-1; j>=0;j--) {
				if(num[i] < num[j]) {
					//因为是往前遍历,只要前面的值比当前的值大,就获取它的索引
					//最后获取的索引肯定最前面比当前的值的大的索引
					index = j;
				}
			}
			//看看索引改变了没有,改变说明需要插入,还要挪动数组
			if(i != index) {
				//记录当前的值,
				int minIndex = num[i];
				for(int j = i;j>index;j--) {//索引index到i-1之间的值都要往后挪一步
					num[j]=num[j-1];
					
				}
				//直接把记录的值赋给数组中索引为index的位置
				num[index] = minIndex;
			}
			
		}
		//输出排序后的结果
		for(int i =0;i< num.length;i++) {
			System.out.print(num[i]+" ");
		}
	}
}

在这里插入图片描述

4、归并排序

参考[图解] 归并排序
归并排序分为两步,拆分再合并,拆分成很多小的新数组(一个值一个的数组),再通过比较合成一个两个按从小到大排序的数组(如果是两个长度为2的合并就是合并成长度为4的数组)

public class Main3 {
	
//把需要插入排序的数组传进这里面	
public static void mergeSort(int[] arr) {
	sort(arr,0,arr.length-1);
}
//开始分解,递归
public static void sort(int []arr,int L,int R) {
	if(L==R) {
		return;
	}
	 int mid = (L + R)/2;
	 //左
	sort(arr, L, mid);
	//右
	sort(arr,mid+1,R);
	//合并
	merge(arr, L, mid, R);
}
//这里进行数组的合并
public static void merge(int[] arr,int L,int mid,int R) {
	int [] temp = new int[R-L+1];
	//记录新数组的索引
	int i =0;
	//第一部分数组的索引
	int p1=L;
	//第二部分数组的索引
	int p2=mid+1;
	//进行插入,直到一方数组没值了
	while(p1 <= mid && p2<=R) {
		// 比较左右两部分的元素,哪个小,把那个元素填入temp中,
		if(arr[p1]<arr[p2]) {
			temp[i++]=arr[p1++];
		}else {
			temp[i++]=arr[p2++];
		}
	}
	// 上面的循环退出后,肯定还有一个数组还有剩余的元素,之后剩余的元素依次填入到temp中
    // 以下两个while只有一个会执行
	while(p1<=mid) {
		temp[i++] = arr[p1++];
	}
	while(p2<=R) {
		temp[i++] = arr[p2++];
	}
	//新数组的值替换旧数组中指定位置的值
	for(i=0;i<temp.length;i++) {
		arr[L+i] = temp[i];
	}
}
public static void main(String[] args) {

	//输入测试用例
	int [] num = new int [] {5,4,7,8,9,5,1,3};
	mergeSort(num);
	//输出排序后的结果
	for(int i =0;i< num.length;i++) {
		System.out.print(num[i]+" ");
	}

}
}

5、快速排序

快速排序有很多种排序,主要的区别就是你选的基准数是怎么选的,而造成了有很多的快速排序的分支
参考快速排序
如果你看上面的还是没看懂可以去快速排序—(面试碰到过好几次)看一看快速排序的步骤
这里以数组的第一个数为基准数做个例子

public class Main4 {
	//递归排序
	public static void quick_sort1(int num[] , int l, int r) {
		if(l < r) {
			int i = l;  //数组的左边边界
			int j = r;	//数组的右边边界
			int x = num[l]; //这个就是基准数
			while(i < j) {   //开始遍历
				while(i<j&&num[j]>=x) {		//从数组的右边开始向前遍历,找到第一个小于基准数的位置
					j--;
				}
				if(i<j) {
					num[i++] = num[j];	 //基准数的位置的值换成了从右边遍历第一个小于基准数的值
				}
				while(i<j &&num[i]<x) {	  //再开始从左边开始遍历找到第一个大于基准数的位置
					i++;
				}
				if(i<j) {
					num[j--] = num[i];		//从左边遍历的第一个大于基准数的值放在上面那个num[j]的位置
				}	
			}	
			num[i]=x;
			quick_sort1(num, l, i-1);	//开始递归基准数的左边数组
			quick_sort1(num, i+1, r);	//开始递归基准数的右边数组
		}
	}
	public static void main(String[] args) {
		//输入测试用例
		int [] num = new int [] {57,88,60,42,83,73,48,85};
		quick_sort1(num, 0, num.length-1);
		//输出排序后的结果
		for(int i =0;i< num.length;i++) {
			System.out.print(num[i]+" ");
		}
	}
}

6、堆排序

import java.util.Arrays;

/**
 * @author 作者
 * @data 2019年8月29日 
 */
public class Main5 {
	public static void main(String[] args) {
		int arr[] = {0,8,2,3,9,5,6};
		int length = arr.length-1;
		//调整为大根堆
		for(int i =length/2;i>0;i--) {
			adjustHeap(arr, i, length);
		}
		System.out.println(Arrays.toString(arr));
		//和第一个元素交换,然后调整为最大堆,因为最大堆的第一个是最大的,所以肯定排在数组的最后面
		//这个相当于选择排序中从后面往前确认数组的值
		for(int i =length;i>1;i--) {
			int num = arr[i];
			arr[i]=arr[1];
			arr[1] = num;
			adjustHeap(arr, 1, i-1);
		}
		System.out.println(Arrays.toString(arr));
	}
	public static void adjustHeap(int arr[],int s,int e) {
		int temp = arr[s];
		for(int i =s*2;i<=e;i++) {
			if(i<e&&arr[i]<arr[i+1]) {
				i++;
			}
			if(arr[i]<=temp) {
				break;
			}
			arr[s] = arr[i];
			s=i;
		}
		arr[s] =temp;
	}
}

发布了213 篇原创文章 · 获赞 22 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_43113679/article/details/100120676