java基础-7
- 冒泡排序
- 选择排序
- 插入排序
- 二分法查找数值
介绍三种常用且逻辑较为简单的排序算法,以下做法中,目标顺序默认升序
冒泡排序
/*冒泡排序的基本逻辑是:
在由前向后逐步遍历数组的过程中,对比当前元素和下一个元素的大小;
若当前元素大于下一个元素,则调换两个元素的位置;
否则不进行操作;
需注意的是,上述操作需要多轮才能完成排序目的;
可以直接进行上述操作多次,次数为数组容量大小,可以确保完成目的,
但实际大部分情况不需要这么多次;
也可以在每次操作之后进行判断,判断结果是否已满足目标,
即本轮是否修改了元素顺序;若无则说明已完成目标
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for(int i=0;i<arr.length;i++){
boolean flag=false;//标记本次是否修改了数组
for(int j=0;j<arr.length-1-i;j++){//每循环一次,从后向前数必定增加一个确定位置的元素
if(arr[j]>arr[j+1]){//当前元素大于后一位的元素,则调换位置
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=true;//本轮进行了修改
}
}
if(!flag){//未进行修改则跳出循环
break;
}
}
System.out.println(Arrays.toString(arr));//输出结果
选择排序
/*选择排序的基本逻辑是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for(int i=0;i<arr.length-1;i++){//当i完成倒数第二个元素时,排序就已完成
int temp=arr[i];//临时变量接收i位置的元素
int position=i;//用于记录最小值的下标
for(int j=i+1;j<arr.length;j++){//从i之后起算,i之前的已排序完成
if(arr[j]<temp){
temp=arr[j];
position=j;
}
}
arr[position]=arr[i];//将i位置的元素放到标记位置
arr[i]=temp;
}
System.out.println(Arrays.toString(arr));//输出结果
插入排序
/*插入排序的基本逻辑是:在从前向后遍历数组的过程中,认为当前元素之前的已排序完成;
拿到当前元素后,向前查找当前元素应该放置的位置。
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for (int i = 1; i < arr.length; i++) {//遍历从第二个开始,到最后一个结束
int temp=arr[i];//定义临时变量存储当前元素值
boolean flag=true;//表示是否找到了插入位置
for (int j = i-1; j >=0; j--) {
if (arr[j]<=temp){//找到了插入位置
flag=false;
arr[j+1]=temp;//将当前元素放到查找位置的下一位
break;
}else {
arr[j+1]=arr[j];//查找位置的元素后移一位
}
}
if(flag){//查找结束,未找到位置说明当前元素比前面所有都小,放在首位
arr[0]=temp;
}
}
System.out.println(Arrays.toString(arr));//输出结果
二分法查找数值
/*二分法查找数值的基本逻辑是,将要查找的元素与数组中间的元素对比(数组需要经过排序);
若目标元素小于当前元素,则在数组前半部分查找(修改查找边界)
若目标元素大于当前元素,则在数组后半部分查找(修改查找边界)
若目标元素等于当前元素,则输出结果
上述三步多次循环,查找到最后,将目标元素与最后的元素对比,相同则找到,不相同则找不到;
*/
int[] arr={13, 15, 30, 48, 50, 60, 67, 68, 78, 79};//定义初始数组(已排序)
int num=30;//定义要查找的数字
int s=0;//定义查找范围的最小下标
int e=arr.length-1;//定义查找范围的最大下标
while(e-s!=0&&e-s!=1){//s=e或e-s=1时说明范围无法再缩小
int mid=(s+e)/2;
if(num>arr[mid]){
s=mid;//改变范围的最小下标
}else if(num<arr[mid]){
e=mid;//改变范围的最大下标
}else{
System.out.println("找到了"+num+"元素,在数组中的索引为:"+mid);
return;
}
}
/*上面代码改变范围时,也可设置s=mid+1;e=mid-1;
因为mid位置的元素已验证,可减少循环次数,同时避免范围内剩余两个元素的情况
但是由于数组中的元素数值不连续,输入不包含的数值时可能会跳出循环(也可以在最后再加一个验证解决);
采用上面的做法可以避免不包含的数值找不到对应输出的情况,但是需要处理剩余两个元素的情况;
*/
if(num==arr[s]){
System.out.println("找到了"+num+"元素,在数组中的索引为:"+s);
return;
}
if(num==arr[e]){
System.out.println("找到了"+num+"元素,在数组中的索引为:"+e);
return;
}
System.out.println("未找到"+num+"元素");