声明: 此笔记通过观看【尚学堂】感悟整理得出, 若有任何相关问题,请注明来源联系作者!
6.4 冒泡排序的基础算法
冒泡排序是常用的排序算法,笔试中非常常见。
算法重复地走访过排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换,使越大的元素会经有交换慢慢“冒泡”到顶端。
步骤:
1、先比较开始相邻的两个元素,如果第一个元素比第二个大,则交换顺序。
2、对每一对相邻的元素做同样的工作,从开始的第一对到结尾的一对。最后的元素为最大的数。
3、再对所有的元素重复以上步骤,除了最后一个。
4、到最后没有一对元素需要比较时,则完成排序。
【如下图】
也可观察下面连接的动态图,比较清晰,容易理解:【https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWFnZXMyMDE3LmNuYmxvZ3MuY29tL2Jsb2cvODQ5NTg5LzIwMTcxMC84NDk1ODktMjAxNzEwMTUyMjMyMzg0NDktMjE0NjE2OTE5Ny5naWY】
声明:此动态图转载于
作者:yyy苏苏【https://blog.csdn.net/qq_41679818/article/details/90296399】此篇文章!
【实例 测试冒泡排序】
//冒泡排序
int[] b = {2,1,3,4,8,0,9,7,5};
int temp = 0;
for(int j = 0;j<b.length;j++) {
boolean flag = true;
for(int i = 0;i<b.length-1-j;i++) {
/*
* 注意:i<b.length会出现数组溢出异常,
* 因为当比较到最后一位时是if(b[4]>b[5]),
* 但数组定义没有b[5].所以会发生错误!
*
*/
if(b[i]>b[i+1]) {
temp = b[i+1];
b[i+1] = b[i];
b[i] = temp;
}
System.out.println(Arrays.toString(b));
//当只有一个循环是得到最大元素,还需要嵌套一个循环,
//把前面的元素再重复比较
【执行结果】
6.4.1 冒泡排序优化算法
初始状态下,整个序列是无序的,有序数列为空,当每一次循环进行时都会将最大的元素排到最后,但不会顾及前面已经不会再循环就已经排好的有序数列(观察如上代码执行结果)。所以,要进行判断每一趟是否发生了数组元素的交换,若没有发生,说明此时数组已经有序,无需再进行后续趟数的比较了。此时可以中止比较。
【实例 测试冒泡排序的优化算法】
//冒泡排序(优化算法)
int[] b = {2,1,3,4,8,0,9,7,5};
int temp = 0;
for(int j = 0;j<b.length;j++) {
boolean flag = true;
for(int i = 0;i<b.length-1-j;i++) {
/*
* 注意:i<b.length会出现数组溢出异常,
* 因为当比较到最后一位时是if(b[4]>b[5]),
* 但数组定义没有b[5].所以会发生错误!
*
*/
//比较大小,换顺序
if(b[i]>b[i+1]) {
temp = b[i+1];
b[i+1] = b[i];
b[i] = temp;
flag = false;
}
System.out.println(Arrays.toString(b));
//当只有一个循环是得到最大元素,还需要嵌套一个循环,
//把前面的元素再重复比较
}
if(flag) {
System.out.println("结束!!");
break;
}
System.out.println("------------");
}
【执行结果】
6.5二分法查找(折半检索)
二分检索又称折半检索。检索的前提条件是:数组的元素要从小到大的排序存放在数组中,给出需要检索的元素与数组的中间元素(key)比较,如果相等,则检索成功!
若比key小,则在数组的前半部分进行二分法检索;
若比key大,则在数组的后半部分进行二分法检索。
【示意图】
【实例 二分法检索测试】
import java.util.Arrays;
/**
* 二分法查找
* @author 卟淡
*
*/
public class ArrayBinarySeach {
public static void main(String[] args) {
int [] test = {15,12,16,10,17,19,18};
Arrays.sort(test); //排序(升序)
System.out.println(Arrays.toString(test)); //输出完整数组
System.out.println("该元素的位置为:" + Test(test,19));
}
public static int Test(int[] test,int value) {
//初始化开头结尾变量
int low = 0;
int high = test.length-1;
while(low <= high) {
int mid = (low+high)/2;
if(value==test[mid]) {
return mid;
}
if(value > test[mid]) { //检索的数比中间数大,则在右边取半进行检索
low = mid +1;//中间一位加1赋回给low,再加最后一位位置数除以2,再继续向右进行折半检索。
}
if(value < test[mid]) {
high = mid-1;//中间一位减1赋回给high,再加第一位元素位置(0),在继续向左折半检索。
}
}
return -1; //若low>high,则无法找到检索的数,返回-1值
}
}
说明:
若检索的数比中间数大,则在右边取半进行检索,中间一位加1赋回给low,再加最后一位位置数除以2,再继续向右折半检索。若检索的数比中间数小,则在左边取半进行检索,中间一位减1赋回给high,再加第一位元素位置(0),在继续向左折半检索。