图解java中各种排序算法以及二分查找

1.冒泡排序

冒泡排序是相对简单的排序算法,大家接触的第一个排序算法应该也是冒泡排序。其中最主要的是理解每次排序的过程是选出了其中最大的一位放在了数组末尾
在这里插入图片描述
附上一段有所改良的java实现的冒泡排序

import java.util.Arrays;
public class 冒泡排序 {
	public static void main(String[] args) {
		int[] a = new int[]{1,4,2,3,5,7};
		boolSort(a);
		System.out.println(Arrays.toString(a));//将数组转为字符输出上面需要导包
	}
	public static void boolSort(int[] a){
		for(int i = 1 ; i <= a.length - 1;i++) {//排几次,排序的次数等于数组元素的个数-1这个很好理解类似5个数有两两比较比4次就好了
			boolean flag = false;//因为某次就把数组排序排好了
			for (int j = 0;j < a.length - i ;j++ ) {
				if(a[j] > a[j+1]) {
					a[j] ^= a[j+1];
					a[j+1] ^= a[j];
					a[j] ^= a[j+1];
					flag = true;//假如这次有排序则代表还没排好
				}
			}
			if(flag == false) {//代码已经排好了 跳出循环
				break;
			}
		}
	}
}

在这里插入图片描述

2.插入排序

插入排序中有两种插入排序
一个是普通的插入排序 另一个是折半插入排序
插入排序说白了就是好比把一个数组分成了两部分,第一个元素是一部分剩下的元素是一部分,第一个元素就一个嘛好比它已经排好了,剩下的元素依次每个插入。插入的时候找到一个适合的位置即找到第一个比当前元素小的位置,然后该位置后的元素都后移。
折半插入排序就是就是用了折半选择思想在前部分已经排序的元素里找到合适的位置,不是一个一个比而是折半的找,效率更高。
先来普通的插入排序
假设有数组 1 3 5 7 2现前4个元素已经排序好了现在要排2。
2先和7比较 2 <= 7 7后移
2再和5比较 2 <= 5 5后移
2再和3比较 2 <=3 3后移
注意比到1的时候 现在指向的位置是1这个位置,发现2比大所有好了 把2插到空着的位置就Ok
在这里插入图片描述

import java.util.Arrays;
public class 折半插入 {
	public static void main(String[] args) {
		int[] a = new int[]{1,3,5,7,2};
		binaryInsert(a);
		System.out.println(Arrays.toString(a));
	} 
	public static void binaryInsert(int[] a) {
		for (int j = 1;j < a.length ;j++ ) {
			int k = a[j];
			int start = 0;
			int end = j-1;
			int mid = 0;
			while(start <= end) {
				mid = (start + end) / 2;
				if( k < a[mid]) {
					end = mid - 1;
				}else {
					start = mid + 1;
				}
			}
			for (int i = j -1;i >= start ; i--) {
				a[i+1] = a[i];
			}
			a[start] = k; 
		}
	
	}
}

在这里插入图片描述

3.折半插入

在讲折半插入前先讲一下二分查找把
现在有一个给定的数组让你找看某个数在不在该数组中,最笨的方法就是写个For循环从数组的头循环到数组的尾巴,找到了就返回该数并break。但是如果数组很大怎么办?这个方法显然会超时(运行时间较长)。但是用二分可以很好的解决这个问题,先从数组中间位置找,看看要找的这个数是不是就是中间这个数如果是那好了直接返回,如果不是的话可以分为两种情况,一种是中间的值比你要找的数大(这里强调个前提哈,二分只能对已经排序好的数组使用)那么很明显你要找的值可能在前一部分,所以直接不考虑中间值及其后面的部分,重点关注中间值前面的额这部分。再来一次刚才的操作。如果比到开始的标志比结束的标志还大还没有找到你要的值,(这里不好理解如果你不懂的话继续往后看)说明你要的值就不存在。

import java.util.Scanner;
public class 二分查找 {
	public static void main(String[] args) {
		int[] a = new int[]{1,2,3,4,5,6};
		Scanner sc = new Scanner(System.in);
		int x = sc.nextInt();
		if(binarySearch(a,x) != -1) {
			System.out.println("该元素在数组的位置是: " + binarySearch(a,x));
		}else {
			System.out.println("不存在");
		}
		
	}
	public static int binarySearch(int[] a,int value) {
		int start = 0;
		int end = a.length - 1;
		int mid;
		while(start <= end) {//=如果就一个数组值 如果没有等号就无法查看
			mid = (start + end)/2;
			if(value == a[mid]) {
				return mid;
			}else if(value < a[mid]) {//记得写[],要不了数组长度是偶数找不到偶数位的值奇数的话找不到奇数位的值
				end = mid -1 ;
			}else {
				start = mid + 1;
			}
		}
		return -1;
	
	}
}

折半插入就是在普通插入的基础上采用了二分来找插入点
先上代码把 这个画图太麻烦 还没掌握好的画图工具如果有幸近期学会了来补上图
比如有 1 3 5 7 现在要插入6 开始位置在1 结束位置在 7
先找到 1 3 5 7 中的中间位置 3
3比6小 则 该插入的位置在右边 现在开始位置在5 结束位置在7
5 7 中间位置在 5 5比 6小 所以在右边 开始位置在7 结束位置也在7
然而while循环还没有结束 继续进行 中间位置结束位置开始位置都在7上 6小于7结束位置-1
现在start在 7这 而 end 在 5这 while中的条件不成立了 结束
发现start就是那会要插入的位置所以在写个循环将要7以及的元素后移 把6插到7的位置上

import java.util.Arrays;
public class 折半插入 {
	public static void main(String[] args) {
		int[] a = new int[]{1,3,5,7,2};
		binaryInsert(a);
		System.out.println(Arrays.toStri ng(a));
	} 
	public static void binaryInsert(int[] a) {
		for (int j = 1;j < a.length ;j++ ) {
			int k = a[j];
			int start = 0;
			int end = j-1;
			int mid = 0;
			while(start <= end) {
				mid = (start + end) / 2;
				if( k < a[mid]) {
					end = mid - 1;
				}else {
					start = mid + 1;
				}
			}
			for (int i = j -1;i >= start ; i--) {//start所在的位置就是while循环结束的位置同时也是要插入的位置
				a[i+1] = a[i];
			}
			a[start] = k; 
		}
	
	}
}

4.快速排序

目前认为最牛逼的排序算法 我学的少/ 见谅
快排推荐大家搜白话经典各种排序算法 那个作者已经写的超级好了 我这里只是加点细节讲解

import java.util.Scanner;
import java.util.Arrays;
public class 快速排序 {
	public static void main(String[] args) {
		int[] a = new int[]{1,3,2,5,7};
		quickSort(a,0,a.length-1);
		System.out.println(Arrays.toString(a));
	}
	public static void quickSort(int[] a,int l,int r) {
		if(l < r) {//初次和递归时候的条件判断
			int i = l;
			int j = r;
			int k = a[l];
			while(i  <  j) {//如果数据多了必须while多次挖坑填坑
				while(i  <  j  &&  a[j]  >=  k) {
					j--;
				}
				if(i  <  j) {//假如进来的是个已经有顺的数组则必须有这个判断条件
					a[i++] = a[j];
				}
				while(i < j && a[j] < k) {
					i++;
				}
				if (i < j){
					a[j--] = a[i];
				}
			}
			a[i] = k;
			quickSort(a,l,i-1);
			quickSort(a,i+1,r);
		}	
	
	}
}

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值