Java学习日记 2022.6.26


算法的时间复杂度

⑴ 找出算法中的基本语句;

算法中执行次数最多的语句,通常是最内层循环的循环体。

⑵ 计算基本语句的执行次数的数量级;

只需保留f(n)中的最高次幂正确即可,忽略所有的低次幂和最高次幂的系数。

⑶ 用大Ο记号表示算法的时间性能。

将基本语句执行次数的数量级放入大Ο记号中。例如:

  for (i=1; i<=n; i++)
  x++;
 
  for (i=1; i<=n; i++)
    for (j=1; j<=n; j++)
      x++;

其中第一个for循环的时间复杂度为Ο(n),第二个for循环的时间复杂度为Ο(n²),则整个算法的时间复杂度为Ο(n+n²)=Ο(n²)。
  注、加法原则:T(n)=O(f(n))+O(g(n))=O(max(fn,gn))
  常见的算法时间复杂度由小到大依次为:

Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n²)<Ο(n³)<…<Ο(2^n)<Ο(n!)<O(n^n)

冒泡排序(Bubble Sort)

算法描述:

	比较相邻的元素。如果第一个比第二个大,就交换它们两个;
	对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
	针对所有的元素重复以上的步骤,除了最后一个; 
	重复步骤1~3,直到排序完成。

代码实现

public class Bubble {

    static Random random = new Random();
    static int[] arr = new int[10];

    public static void main(String[] args) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("冒泡排序前的数组:" + Arrays.toString(arr));
        bubbleSort();
        System.out.println("冒泡排序后的数组:" + Arrays.toString(arr));
    }

    public static void bubbleSort(){

        if (arr == null || arr.length <= 1){
            return;
        }

        for (int i = 0; i < arr.length; 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;
                }
            }
        }
    }
}

运行结果:

冒泡排序

算法分析

最佳情况:T(n) = O(n) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
稳定性:稳定。

选择排序

算法描述:

n个记录的直接选择排序可经过n-1趟直接选择排序得到有序结果。具体算法描述如下:

	初始状态:无序区为R[1…n],有序区为空;
	第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1…i-1]		和R(i…n)。该趟排序从当前无序区中-选出关键字最
小的记录R[k],将它与无序区的第1个记录R交换,使R[1…i]和R[i+1…n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
	n-1趟结束,数组有序化了。

代码实现

public class Choice {
    static Random random = new Random();
    static int[] arr = new int[10];

    public static void main(String[] args) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("选择排序前的数组:" + Arrays.toString(arr));
        choiceSort();
        System.out.println("选择排序后的数组:" + Arrays.toString(arr));
    }

    public static void choiceSort(){
        if (arr == null || arr.length <= 1){
            return;
        }

        for (int i = 0; i < arr.length - 1; i++) {
            int min = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]){
                    min = j;
                }
            }
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
}

运行结果:

在这里插入图片描述

算法分析

最佳情况:T(n) = O(n2) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(n2)
稳定性:不稳定。

直接插入排序

算法描述:

从第一个元素开始,该元素可以认为已经被排序; 
取出下一个元素,在已经排序的元素序列中从后向前扫描;
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
将新元素插入到该位置后; 重复步骤2~5。

代码实现

public class Insert {
    static Random random = new Random();
    static int[] arr = new int[10];

    public static void main(String[] args) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("直接插入排序前的数组:" + Arrays.toString(arr));
        InsertSort();
        System.out.println("直接插入排序后的数组:" + Arrays.toString(arr));

    }

    public static void InsertSort(){
        if (arr == null || arr.length <= 1){
            return;
        }
        for (int i = 1; i < arr.length; i++) {
            int insert = arr[i];
            int j = i-1;
            while(j >= 0 && arr[j] > insert){
                arr[j + 1] = arr[j];
                j--;
            }
            arr[j + 1] = insert;
        }
    }
}

运行结果:

在这里插入图片描述

算法分析

最佳情况:T(n) = O(n) 最坏情况:T(n) = O(n2) 平均情况:T(n) = O(n2)

快速排序

算法描述:

	从数列中挑出一个元素,称为 “基准”(pivot);
	重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之
后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
	递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

代码实现

public class Quick {
    static Random random = new Random();
    static int[] arr = new int[10];

    public static void main(String[] args) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("快速排序前的数组:" + Arrays.toString(arr));
        QuickSort(arr,0, arr.length-1);
        System.out.println("快速排序后的数组:" + Arrays.toString(arr));

    }

    public static void QuickSort(int[] src, int begin, int end){
        if (arr == null || arr.length <= 1){
            return;
        }
        if (begin < end){
            int key = arr[begin];
            int i = begin;
            int j = end;
            while(i<j){
                while (i < j && src[j] > key){
                    j--;
                }
                if(i < j){
                    src[i] = src[j];
                }
                while (i < j && src[i] < key){
                    i++;
                }
                if (i < j){
                    src[j]  = src[i];
                }
            }
            src[i] = key;
            QuickSort(src,begin,i-1);
            QuickSort(src, i+1, end);
        }
    }
}

运行结果:

在这里插入图片描述

算法分析

最佳情况:T(n) = O(nlogn) 最差情况:T(n) = O(n2) 平均情况:T(n) = O(nlogn)
稳定性:不稳定。

希尔排序

算法描述

	选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1; 
	按增量序列个数k,对序列进行k 趟排序;
	每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1
时,整个序列作为一个表来处理,表长度即为整个序列的长度。

代码实现

public class Shell {
    static Random random = new Random();
    static int[] arr = new int[10];

    public static void main(String[] args) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("希尔排序前的数组:" + Arrays.toString(arr));
        ShellSort();
        System.out.println("希尔排序后的数组:" + Arrays.toString(arr));
    }

    public static void ShellSort(){
        for (int d = arr.length/2; d > 0; d /= 2){
            for (int i = d; i < arr.length; i++) {
                for (int j = i - d; j >= 0; j -= d){
                    if (arr[j] > arr[j + d]){
                        int temp = arr[j];
                        arr[j] = arr[j + d];
                        arr[j + d] = temp;
                    }
                }
            }
        }
    }
}

运行结果

在这里插入图片描述

算法分析

最佳情况:T(n) = O(nlog2 n) 最坏情况:T(n) = O(nlog2 n) 平均情况:T(n) =O(nlog2n)
稳定性:不稳定。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值