1、时间复杂度和简单排序

预备知识

1、时间复杂度

①常数的时间操作:一个操作如果和数据量没有关系,每次都是固定时间操作,叫做常数操作。
②时间复杂度常用O(读作big O)来表示。具体来说,在常数操作数量的表达式中,
只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分记为f(N),那么时间复杂度记为
O(f(N))。

例1、时间复杂度的例子

对一个长度为N的数组进行排序:
算法:依次从0—-N-1个数中选出最小的数,放在数组的0位置
  从1—N-2个数中选出最小的数,放在数组的1位置
&nbsp&nbsp从2—N-3个数中选出最小的数,放在数组的2位置
time=N+(N-1)+(N-2)**+1=(N+1)N/2
只要高阶项,不要低阶项,也不要高阶项的系数
所以时间复杂度位O(N*N)

例2、时间复杂度的例子

一个有序数组A,另一个无序数组B,请打印B中所有不在A中的数,A数组的长度为N,
B数组的长度为M。
·算法1:对于数组B中的每一个数,都在A中通过遍历的方式找一下;
·算法2:对于数组B中的每一个数,都在A中通过二分的方式查找一下;
·算法3:先把B中的数进行排序,然后用类似外排的方式打印所有不在A中出现的数。
计算时间复杂度:
1、O(M*N)
2、①对有序的数组,二分查找的时间复杂度O(logN) 底数为2
      在1,3,5,6,8,10中找出x
      L………………R
      mid=(L+R)/2 ,根据,数组[mid]与x比较大小的结果,确定下一次二分的方向,N个数二分最多能分logN次。
②所以算法2的时间复杂度为 O(M*logN)
3、
①对无序数组使用基于比较的排序算法O(M*logM)
②1,3,5,7,10,16,18;2,4,8,17,20
….a…………………….b…………
使用类似外排的方式:如果a

2、排序算法

①冒泡排序

//O(N*N)
package Day01;

public class Day01_bubbleSort {
    public static  void  bubbleSort(int[] arr){
            /*1、判断数组的长度*/
            if (arr==null||arr.length<2){
                System.out.print("数组太短无法满足要求");
            }
            for(int end=arr.length-1;end>0;end--){
            for (int i=0;i<end;i++){
                if (arr[i]>arr[i+1]){
                    swap(arr,i,i+1);
                }
            }
        }

    }
    public static void swap(int[] arr,int i,int j){
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;

    }
    public static void main(String[] args) {
//        int[] a=[1,3,50,39,28,100,3,6,30]
        int[] a={1,3,50,39,28,100,3,6,30};
        Day01_bubbleSort.bubbleSort(a);
        for (int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }
}

2、选择排序

public class Day01_SelectionSort {
    /*算法:依次从0----N-1个数中选出最小的数,放在数组的0位置;
    从1---N-2个数中选出最小的数,放在数组的1位置
    从2---N-3个数中选出最小的数,放在数组的2位置
    O(N*N)
    */
    public static void  selectionSort(int[] arr){
        /*1、判断数组的长度*/
        if (arr==null||arr.length<2){
            System.out.print("无法满足要求.....");
            return ;
        }
        for(int i=0;i<arr.length-1;i++){
            int minIndex=i;
            for (int j=i+1;j<arr.length;j++){
                minIndex=arr[j]<arr[minIndex]? j  :  minIndex;
            }
            swap(arr,i,minIndex);
        }
    }
    public static void swap(int[] arr,int i,int j){
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;

    }
    public static void main(String[] args) {
        int[] a={1,3,50,39,28,100,3,6,30};
        Day01_SelectionSort.selectionSort(a);
        for(int i=0;i<a.length;i++){
            System.out.println(a[i]);
        }
    }
}

3、插入排序

package Day01;
/*输入:一个含有N个元素的数组
* 1、遍历数组的下标    1.......N-1
* 2、依次把下标所对应的元素与前一个元素进行比较,小于之前的元素就交换,并不断比较
*
*时间复杂度O(N^2)
*
* 最好O(N)
* 最坏O(N^2)
*
* */
public class Day01_InstertionSorting {
    public static void InsertionSorting(int [] arr){
        if (arr==null||arr.length<2){
            System.out.print("无法满足要求.....");
            return ;
        }
        for (int i=1;i<arr.length;i++){
            for(int j=i;j>=0;j--){
                if (arr[j-1]>arr[j]){
                    swap(arr,j-1,j);
                }
                else {
                    j=-1;
                }
            }
        }
    }
    private static void swap(int[] arr, int i, int j) {
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;
    }

    public static void main(String[] args) {
    int[] arr={1,3,2,29,30,42,14,11,18,20,100,50};
    Day01_InstertionSorting.InsertionSorting(arr);
        for (int arr_ele:arr){
            System.out.println(arr_ele);
        }
    }
}

3、递归的时间复杂度和master公式

(1)用递归的方法求最大值

public class Day01_recursion {
    public static int getMAx(int [] arr,int L,int R){
        if (L==R){
            return arr[L];
        }
        int mid=(L+R)/2;
        int maxLeft=getMAx(arr,L,mid);
        int maxRight=getMAx(arr,mid+1,R);
        return Math.max(maxLeft,maxRight);
    }
    public static void main(String[] args) {
        int []arr={11,2,1,4,50,8,23,36,13,46,90};
        System.out.println(Day01_recursion.getMAx(arr,0,8));
    }
}

(2)主定理(master Theorem)

设a>=1,b>1为常数,f(n)为函数,T(n)为非负整数,且

T(n)=aT(n/b)+f(n)

a是归约后子问题的个数
b是子问题的规模
f(n)是归约过程及组合子问题解的工作量

Alt text


如归并排序:T(n)=2T(n/2)+O(N)
带入公式其时间复杂度为O(n*logn)

4、归并排序


package Day01;
/*
归并排序的时间复杂度是O(N*lgN)
T(n)=2T(n/2)+O(N)
* */
public class Day01_mergeSort {
    public static void  mergeSort(int[] arr){
        if(arr==null||arr.length<2){
            return;
        }
        sortProcess(arr,0,arr.length-1);
    }
    public static void sortProcess(int[]arr,int L,int R){
        if(L==R){
            return;
        }
        int mid=(L+R)/2;
        sortProcess(arr,L,mid);//T(2/n)
        sortProcess(arr, mid+1, R);//T(2/n)
        merge(arr,L,mid,R);//O(n)
    }
    public static void merge(int [] arr,int L,int mid,int R){
        int [] help=new int[R-L+1];
        int p1=L;
        int p2=mid+1;
        int i=0;
        while (p1<=mid && p2<=R){
           help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];//比较完之后,向右移动一位
        }
        while (p1<=mid){
            help[i++]=arr[p1++];
        }
        while (p2<=R){
            help[i++]=arr[p2++];
        }
        for (i=0;i<help.length;i++){
            arr[L+i]=help[i];
        }
    }

    public static void main(String[] args) {
        int[]arr={1,2,1,5,7,0,100,40,20,19,12,10,16};
     Day01_mergeSort.mergeSort(arr);
     for (int i=0;i<arr.length;i++){
         System.out.println(arr[i]);
     }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值