java选择排序 冒泡排序【vaynexiao】

选择排序 冒泡排序

	public static void main(String[] args){
    
    
		
		int arr[] = {
    
    3,5,7,2,8,1,9,6,4};
		System.out.print("排序前:");printfArray(arr);
		selectSort(arr);
		System.out.print("选择排序后:");printfArray(arr);
		
		int arr2[] = {
    
    3,5,7,2,8,1,9,6,4};
		System.out.print("排序前:");printfArray(arr2);
		bubbleSort(arr2);
		System.out.print("冒泡排序后");printfArray(arr2);
	}
	//选择排序(升序)从左往右取出一个数,这个数依次和其他数比较,大于则交换,即得到最小的数,10轮结束也就得到升序结果
	public static void selectSort(int[] arr){
    
    
		for(int x=0; x<arr.length-1; x++){
    
    
			//将第1个元素和其他元素逐个比较,左边大就叫唤,为了让第1个元素为最小元素
            //每次循环后,每次循环都可以得到一个当前最小值
			for(int y=x+1; y<arr.length; y++){
    
    
				if(arr[x]>arr[y]){
    
    
					int temp = arr[x];
					arr[x] = arr[y];
					arr[y] = temp;
				}
			}
		}
	}
	//冒泡排序(升序)比较第1丶2个数,1大于2则交换,继续比较2丶3个数,直至首轮结束,得到最大数,进行10轮得到升序结果
	//bubble排序是一种稳定排序,值相等的元素不会改变顺序。
	//由于该算法每一轮遍历所有元素,共遍历(元素数量-1)轮。
	public static void bubbleSort(int[] arr){
    
    
		for(int x=0;x<arr.length-1;x++){
    
    
			for(int y=0;y<arr.length-1-x;y++){
    
    
				if(arr[y]>arr[y+1]){
    
    
					int temp = arr[y+1];
					arr[y+1] = arr[y];
					arr[y] = temp;
				}
			}
		}
	}
	public static void printfArray(int[] arr){
    
    
		System.out.print("[");
		for(int i=0;i<arr.length;i++){
    
    
			if(i!=arr.length-1){
    
    
				System.out.print(arr[i]+",");
			}else{
    
    
				System.out.println(arr[i]+"]");
			}
		}
		
	}

冒泡排序优化

	//冒泡排序优化版(针对循环至中期顺序已排好的情况)
    public static void bubbleSort2(int[] arr){
    
    
        for(int x=0;x<arr.length-1;x++){
    
    
            //有序标记,每一轮的初始是true
            boolean isSorted = true;
            for(int y=0;y<arr.length-1-x;y++){
    
    
                if(arr[y]>arr[y+1]){
    
    
                    int temp = arr[y+1];
                    arr[y+1] = arr[y];
                    arr[y] = temp;
                    //有元素交换,所以不是有序,标记变为false
                    isSorted = false;
                }
            }
            //如果一整轮都没有元素被调换,说明排序已完成,可以直接跳出
            if(isSorted){
    
    
                break;
            }
        }
    }
34215678
这个数列的特点是前半部分(3421)无序,后半部分(5678)升序,并且后半部分的元素已经是数列最大值。
其实一部分已经是有序的了,不需要重复进行遍历比较了。

这个问题的关键点在哪里呢?关键在于对数列有序区的界定。
按照现有的逻辑,有序区的长度和排序的轮数是相等的。比如第一轮排序过后的有序区长度是1,第二轮排序过后的有序区长度是2 ......
实际上,数列真正的有序区可能会大于这个长度,比如例子中仅仅第二轮,后面5个元素实际都已经属于有序区。因此后面的许多次元素比较是没有意义的。
如何避免这种情况呢?我们可以在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。

	//冒泡排序优化版(针对循环至中期顺序已排好的情况)
    public static void bubbleSort3(int arr[], int len) {
    
    
        int i = 0;
        int tmp = 0;
        int flag = 0;
        int pos = 0;//用来记录最后一次交换的位置
        int k = len - 1;
        for (i = 0; i < len - 1; i++){
    
    //确定排序趟数
            pos = 0;
            int j = 0;
            flag = 0;
            for (j = 0; j < k; j++){
    
    //确定比较次数
                if (arr[j]>arr[j + 1]){
    
    
                    //交换
                    tmp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = tmp;
                    flag = 1;//加入标记
                    pos = j;//交换元素,记录最后一次交换的位置
                }
            }
            if (flag == 0){
    
    //如果没有交换过元素,则已经有序
                return;
            }
            k = pos;//下一次比较到记录位置即可
        }
    }

猜你喜欢

转载自blog.csdn.net/vayne_xiao/article/details/109080077