冒泡排序,快速排序,选择排序(java)

七大排序

排序方法平均复杂度最坏复杂度最好复杂度辅助空间稳定性
选择排序O(n^2)O(n^2)O(n^2)O(1)稳定
冒泡排序O(n^2)O(n^2)O(n^2)O(1)稳定
插入排序O(n^2)O(n^2)O(n^2)O(1)稳定
归并排序O(nlogn)O(nlogn)O(nlogn)O(n)稳定
快速排序O(nlogn)O(n^2)O(nlogn)O(1)不稳定
希尔排序O(nlogn)~O(n^2)O(n^1.3)O(n^2)O(logn)~O(n)不稳定
堆排序O(nlogn)O(nlogn)O(nlogn)O(1)不稳定




1.冒泡排序

简单解释

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

看图更容易理解
在这里插入图片描述
下面是代码

 public static void bubbleSort(int arr[]) {
 
        for(int i =0 ; i<arr.length-1 ; i++) { 
           
            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;
            }
            }    
        }
    }

这里解释一下第二个for里面j<arr.length-1-i.为什么要-i呢,这个问题比较简单;

第一次i=0的时候,第二层循环依次比较j与j+1的大小,此次循环会把整个数组的最小值交换到最末尾的位置(假设排序是从大到小),当i=1时,此次循环会把整个数组第二个小的数交换到末尾位置(每次循环前面的数据都会有一定的改变,大数逐渐前移),以此类推。所以第二层循环比较到a.length是没有意义的,故通过j<a.length-1-i来减少比较次数

要优化一下的话就给他加个标记flag,要你写冒泡排序也尽量写下面这种。

 public static int[] bubbleSort(int arr[]) {
 
         boolean flag;//是否交换的标志
        for(int i =0 ; i<arr.length-1 ; i++) { 
            
			//设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成
			flag = true;
		   
            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 = false;//只有发生了交换,才为false
            }
            }    
        if (flag) {
            break;//判断标志位是否为true,为true说明后面的元素已经有序,直接return出去
		
		}
	 }
		 return arr;  
    }



2.选择排序

简单解释

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。

再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

重复第二步,直到所有元素均排序完毕。

看图
在这里插入图片描述
代码

public static void selectionSort(int[] arr){                
    for(int i = 0; i < arr.length - 1; i++){  // 交换次数        
        // 先假设每次循环时,最小数的索引为i            
        int min = i;// 每一个元素都和剩下的未排序的元素比较          
        for(int j = i + 1; j < arr.length; j++){             
            if(arr[j] < arr[min]){//寻找最小数                   
                min = j;//将最小数的索引保存                
            }           
        }
        //经过一轮循环,就可以找出第一个最小值的索引,然后把最小值放到i的位置           
            if (i != min) {
                int tmp = arr[i];
                arr[i] = arr[min];
                arr[min] = tmp;       
    }   
}

选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²)的时间复杂度。
所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了



3.插入排序

插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。

简单解释

将第一待排序序列第一个元素看做一个有序序列,
把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)

看图
在这里插入图片描述
代码

public static void  insert_sort(int arr[]){

   int temp;

// 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
   for(int i=0;i<arr.lenth-1;i++){
       for(int j=i+1;j>0;j--){  //比较的次数是j和他前面的数据比较,比如第二个就只要和第一个比较,j=2就是比较1次了
           if(array[j] < array[j-1]){  //和他前面的数据进行比较
               temp = array[j-1];
               array[j-1] = array[j];
               array[j] = temp;
           }else{         //不需要交换
               break;
           }
       }
   }
}

快速排序

public static void quickSort2(int[]arr,int left,int right){
        //left指向最左边 0 ,right指向最右边 arr.length-1
        //跳出循环的条件
        if ((left >= right)){
            return;
        }
        //l 和 r 作为指针
        int l = left;
        int r = right;
        while (l < r) {
             //选择left(每次的最左边的数)作为基准比较,直到r指针指向的数比基准小,此时r指向这个数,停止左移
            //l指针同理,直到指向的数比基准大时,停止右移
            while (l < r && arr[r] >= arr[left]) r--;
            while (l < r && arr[l] <= arr[left]) l++;
            //当l和r指针指向同一数,让l或r指针指向的数 跟基准数交换,此时基准数右边一定都是比他大的,左边都是比他小的
            if (l == r){
                int temp = arr[r];
                arr[r] = arr[left];
                arr[left] = temp;
            }else {
                //如果两指针没有指向同一数,让l指向的内容 和 r指向的内容交换
                int temp = arr[r];
                arr[r] = arr[l];
                arr[l] = temp;
            }
        }
        //递归:l指针左边的继续上述操作,r右边一样
        quickSort2(arr, left,l-1);
        quickSort2(arr, r+1, right);

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值