思想:两两比较,大数沉底
第一轮:会有最大数沉底 比较结束后,有1个数不参与下一轮的比较
第二轮:第二大的数沉底 比较结束后,有两个最大会,最大的两个数下一轮不参与比较
...
不管哪一个轮次,两两比较,大数沉底 ,轮次就是循环的量,轮次的索引值为0,每个轮次进行比较,比较的取多次数是n-1,减去一个比较完的数
交换两个数的值
第一种
方法:利用中间变量
Int tmp; //把a,b两值交换
tmp=a//先把a放在第三个引入变量中保存
a=b//报b赋值给a
b=tmp//最后把第三方引入变量的内容存储另外交换的变量中
第二种: 不用第三方变量,是否完成两值交换
Python
a,b=b,a
代鉴
a=a+b
b=a-b
a=a-b
第三种:
Int[] c={a,b}
a=c[1]
b=c[0]
try.....catch处理的不一定就是错误, 可能是编程中的一个思路误区或者毛病,使用try....catch可以防止报错.
二分查找需要超始的索引,和终止的索引.二分查找特点需要查找的值>中间值,在后面找,起始的索引变化,同样,如果需要查找的值<中间值,在前面找,终止的索引变化,
测试:
成功条件: 前面第一个元素,后面最后一个元素,中间任意一个元素
失败条件: 比前面第一个元素小的元系,比最后一个元素大的元素,中间任意一个不存在的元素.
快速排序
方法: 概括分治思维
10个排序,10个数字分段,每段之间的排序
一轮排序得出大值,小值
6 12 3 46 56 25
基数6
第一轮: 前面游标12 到3 3 要到6的左边 3放在0的位置上
后面游标25
只要小的,就把0位置和这个元素换,
3 12 6 46 56 25
结束后,
左游标 停在12的位置上,,最后基数位置和12的位置换掉
3 6 12 46 56 25
把这个数以6分成两部分,左边快速,右边快速,不清楚什么时候快排结束,每次快排都分成两部分
For(){
While(左半部分)
While(右半部分) {
}
}
最好函数
Public void static Quanpai(arr,left,right){
左半部分 Quanpai(arr,mid_left,mid_right)
右半部分Quanpai(arr,mid_left,mid_right)
}
在数组分治中,直接循环很麻烦,最优化就是函数,函数中可以继续调用这个函数,改变参数,这种函数可以在内部调用自己方法,称为递归调用.
注意:
int[] arr={1,2,3,4,5};
int[] arr1=arr;
arr[0]=100;
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr1));
只改变一个数组中的元素,另一个数组已经改变.
数组之间的赋值相当于把地址赋值给数组,不是数据,也就是两个数组变量指向了同一个地址,这个地址中的数据都是一样的,这种变量叫引用变量.
import java.util.Arrays;
public class ShuZu4 {
public static void main(String[] args) {
/*
快速排序
*/
int[] arr={10,30,25,79,40,32,6,25};
//上面的arr是主函数的变量
//调用快排函数,因为快排函数涉及到分治,把数据分成左右两部分,还继续调用
QuaiPai(arr,0,arr.length-1);
// 调用快排后,直接输出
System.out.println(Arrays.toString(arr));
}
//快排需要左和右的游标,每轮都会把数据分成两部分,左部分右部分每轮数值都不一样
//这里传入的 arr是QuaiPai中的变量,但是两个的地址相同,操作都是一个数据,这里操作后不需要返回
public static void QuaiPai(int[] arr,int left,int right) {
//限定函数的退出,对于函数就是return,对于循环就是break
if(left>=right){
return;
}
//记录的left0是基值的位置意思
int left0=left;
//设定基数值,每轮分段后每次以左边的值做为基值,每轮基值就不同了
int baseNumber = arr[left0];
//然后再进行比较
while (left != right) {
//右边的元素比基值,加右游标,右边的游标是--,再++就超出数组的界限
System.out.println(right);
while(arr[right]>=baseNumber && left<right){
right--;
}
System.out.println("--------------");
System.out.println(left);
//左边的元素比基值,加左游标
while(arr[left]<=baseNumber && left<right){
left++;
}
//以上两个条件退出,证明有一个数left游标的值>baseNumber或者右边的元素<=baseNumber
int tmp=arr[right];
arr[right]=arr[left];
arr[left]=tmp;
}
//退出游标left和 right的指示时,再把左游标和基值的位置交换,这样基值左边元素都比基值小,基值右边元素都比基值大
int tmp=arr[left0];
arr[left0]=arr[left];
arr[left]=tmp;
//执行到这里,数组被基值分成左右两部分,左边比基值小,但无序,右边比基值大,也无序
//再次递归调用快排左边和右边
//现在数组分裂点在left的位置,left+1到数组结尾是右边,右边使用快排
QuaiPai(arr,left+1,arr.length-1);
//从left0开始,到right-1
QuaiPai(arr,left0,right-1);
}
}