冒泡排序
直接贴代码:自己写的
//冒泡排序
/*1.比较数组中,两个相邻的元素,如果第一个数比第二个数
大,我们就交换他们的位置 */
//2.每一次比较,都会产生出一个最大,或者最小的数字;
//3.下一轮则可以少一次排序!
//4.依次循环,直到结束
public static void main(String[] args) {
int[] a = {1,2,3,5,4,10,6,8,7,9,12,14};
a = sort(a);
System.out.println(Arrays.toString(a));
}
public static int[] sort(int[] b){
int temp = 0; //作为第三个变量 用来交换用的
int x = 0,y = 0; //x用来记录一共执行了多少次交换
for (int j = b.length - 1; j > 0; j--) {
for (int i = 0; i < j; i++) { //最大的数被换到最后,下一次排序可以不对它进行判断
if(b[i] > b[i + 1]){//改变判断符号即可改变该数组最后是升序还是降序输出
temp = b[i];
b[i] = b[i + 1];
b[i + 1] = temp;
x++;
}
}
if(x == y){ //如果此次循环没有进行交换 说明数组已经完全排序好了 不用再进行多余的排序
break;
}else {
y = x;
}
}
System.out.println(x);
return b;
}
优化算法:
public static int[] sort(int[] b){
int temp = 0;
boolean flag = true; //取消计数功能 用一个布尔值进行判断
for (int j = b.length - 1; j > 0; j--) {
for (int i = 0; i < j; i++) {
if(b[i] > b[i + 1]){
temp = b[i];
b[i] = b[i + 1];
b[i + 1] = temp;
flag = false;//数组做了更改 布尔值变为false
}
}
if(flag){
break; //当数组一次循环没有任何修改 说明该数组已经排好序,跳出循环
}
flag = true;//做了更改,把布尔值变回true,以便下一次循环判断。
}
return b;
}
思考:如果传进来的数组后面已经是排好序的,后面的循环再去排序就是浪费时间.要用一个值来记录后面排序没有做出改变的次数,同时如果做出了改变 还要将这个值修正(前面这种算法的所有可能性包含在这种算法中)
public static int[] sort(int[] b){
int temp = 0;
int flag = 0;//初始值为0
for (int j = b.length - 1; j > 0; j--) {
for (int i = 0; i < j; i++) {
if(b[i] > b[i + 1]){
temp = b[i];
b[i] = b[i + 1];
b[i + 1] = temp;
flag = 0;//做出更改 值修正为0
}else{
flag++;//没做出改变 值加1
}
}
j -= flag;//最后有几个数没有做出改变 用外层循环的j减去这个数字
}
return b;
}
最后,3种算法都成功了。
之后补充双向
思考:如果前面已经是排好的,那每次循环开始也要进行没必要的判断,但正向排序不会把最小的值pop到最前面 所以要使用双向排序
public static int[] sort(int[] b){
int temp = 0;
int flag = 0,//记录数组有没有做出改变
flagA = 0,flagB = 0;//把改变的值储存在A B里 A为正向排序的 B为反向排序的
for (int j = b.length - 1,k = 0; j > 0 && flagA + flagB < b.length - k; j--,k++) {
//k为计数 记录循环执行了多少次
//正向
for (int i = flagB + k; i < j - flagA; i++) {
//循环从flagB + k开始 从j - flagA结束
//flagB + k之前的和j - flagA之后的都是已经排序好的 排序算法没必要对其进行多余的排序
if(b[i ] > b[i + 1]){
temp = b[i];
b[i] = b[i + 1];
b[i + 1] = temp;
flag = 0;//做改变 flag值修正
}else{
flag++;//没做改变 flag值加一
}
}
flagA += flag;//把改变的值储存在
flag = 0;//修正
//反向
for (int i = j - 1 - flagA; i > flagB + k; i--) {
//循环从j - flagA -1开始
//(经过上面的排序最大的数字已经在最后了 没有必要再对它进行排序)
//后面同理
if(b[i] < b[i - 1]){
temp = b[i];
b[i] = b[i - 1];
b[i - 1] = temp;
flag = 0;
}else{
flag++;
}
}
flagB += flag;
flag = 0;
}
return b;
能不能看懂全看天意。
优化一下:
public static int[] sort(int[] b) {
int temp = 0;
int flag = 0;//记录数组有没有做出改变
for (int flagA = 0, flagB = 0; flagA + flagB < b.length; ) {
//把改变的值储存在A B里 A为正向排序的 B为反向排序的
for (int j = flagA; j < b.length - 1 - flagB ; j++) {
//循环从flagA开始 从b.length - 1 - flagB结束
//b.length - 1 - flagB之前的和flagA之后的都是已经排序好的 排序算法没必要对其进行多余的排序
if (b[j] > b[j + 1]) {
temp = b[j + 1];
b[j + 1] = b[j];
b[j] = temp;
flag = 0;//做改变 flag值修正
}else {
flag++;//没做改变 flag值加一
}
}
flagB += flag + 1;//把改变的值储存在flagA中 + 1 是因为上面已经排序好了一位
flag = 0;
for (int j = b.length - 1 - flagB ; j > flagA ; j--) {
if (b[j] < b[j - 1]) {
temp = b[j - 1];
b[j - 1] = b[j];
b[j] = temp;
flag = 0;
}else {
flag ++;
}
}
flagA += flag + 1;
flag = 0;
}
return b;
}