数据结构与算法:高效编程的核心

目录

一、什么是数据结构

二、时间复杂度与空间复杂度

1.时间复杂度

(1)计算func2的时间复杂度

(2)计算func3的时间复杂度

(3)计算func4的时间复杂度

(4)计算bubblesort的时间复杂度

(5)计算binarySearch的时间复杂度

(6)计算factorial的时间复杂度

(7)计算fibonacci的时间复杂度

2.空间复杂度

(1)计算bubblesort的空间复杂度

(2)计算fibonacci的空间复杂度

(3)计算fibonacci的空间复杂度


一、什么是数据结构

数据结构是计算机中存储、组织数据的方式,旨在实现高效的数据访问和操作。它定义了数据元素之间的逻辑关系,以及对这些关系的操作(如插入、删除、搜索等)。数据结构的选择直接影响算法的性能和资源利用率。

数据结构在Java中有具体的实现方式------集合类。在Java标准库中,提供了一些类,我们可以直接使用,有些集合类就是已经实现好的数据结构。我们要学好数据结构的理论功底,就能很好的使用这些集合类。

二、时间复杂度与空间复杂度

它们是衡量一段代码消耗资源开销多少的一种方式,衡量的时候只和代码有关,和使用的机器无关。

1.时间复杂度

站在数学的角度,我们使用问题规模N ,计算关键操作的次数与N之间的函数关系,在进行化简与近似,只取最高次项,把其他项忽略掉,把最高此项的系数也忽略掉,使用大O渐进表示法O()。

(1)计算func2的时间复杂度
java 复制代码
    void func2(int N) {
        int count = 0;
        for (int k = 0; k < 2 * N; k++) {
            count++;
        }
        int M = 10;
        while ((M--) > 10) {
            count++;
        }
        System.out.println(count);
    }

首先我们要先找这个代码的关键操作,count++,在for循环中的count++的循环次数为2N,而while中count++的循环次数为常数10,与N无关;故总的循环次数为2N+10,去掉常数与最高次项的系数,因此func2的时间复杂度为O(N)。

(2)计算func3的时间复杂度
java 复制代码
void func3(int N, int M) {
        int count = 0;
        for (int k = 0; k < M; k++) {
            count++;
        }
        for (int k = 0; k < N ; k++) {
            count++;
        }
        System.out.println(count);
    }

这段代码的关键操作为count++,第一个for循环的循环次数为M,第二个循环的循环次数为N,故时间复杂度为O(M+N)。

(3)计算func4的时间复杂度
java 复制代码
 void func4(int N) {
        int count = 0;
        for (int k = 0; k < 100; k++) {
            count++;
        } 
        System.out.println(count);
    }

这段代码的关键操作为count++,for循环的循环次数为常数100,与问题规模N无关,无论N取多少,都不会影响count++,我们把这种代码的时间复杂度称为O(1)。

(4)计算bubblesort的时间复杂度
java 复制代码
void bubbleSort(int[] array) {
        for (int end = array.length; end > 0; end--) {
            boolean sorted = true;
            for (int i = 1; i < end; i++) {
                if (array[i - 1] > array[i]) {
                    Swap(array, i - 1, i);
                    sorted = false;
                }
            }
            if (sorted == true) {
                break;
            }
        }
    }

最坏时间复杂度 当输入数组完全逆序时,每次内层循环都需要执行完整的比较和交换操作。外层循环运行 n 次(数组长度),内层循环运行次数从 n-1 逐步递减到 1。总操作次数为: [ (n-1) + (n-2) +...... + 1 = (1+N)*N / 2 ] 因此最坏时间复杂度为 (O(n^2))。

(5)计算binarySearch的时间复杂度
java 复制代码
int binarySearch(int[] array, int value) {
        int begin = 0;
        int end = array.length - 1;
        while (begin <= end) {
            int mid = begin + ((end-begin) / 2);
            if (array[mid] < value)
                begin = mid + 1;
            else if (array[mid] > value)
                end = mid - 1;
            else
                return mid;
        } 
        return -1;
    }

这是一段取中间元素的代码,每循环一次,就是让区间范围缩小一半,假设我们的数组元素为8,循环次数为4,如果数组元素为16,循环次数为5,如果数组元素为32,循环次数为6,我们可以推断出数组元素为N时,2^(循环次数-1)=N,循环次数=log₂N+1,时间复杂度为O(log₂N)。

(6)计算factorial的时间复杂度
java 复制代码
long factorial(int N) {
        return N < 2 ? N : factorial(N-1) * N;
    }

虽然没有循环,但是有递归,递归理论上都能转换为循环,假设N为1时,循环1次;假设N为2时,循环为2;N为3时,循环为3......我们可以得出N为几,就循环多少次。故时间复杂度为O(N)。

(7)计算fibonacci的时间复杂度
java 复制代码
int fibonacci(int N) {
        return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
    }

每执行一个方法,就能衍生出两个递归操作,每个递归又能衍生出两个递归操作......,一旦给N设置一个较大的值时,程序就会运行特别慢,时间复杂度为O(2N)

2.空间复杂度

空间复杂度就是衡量代码运行时消耗掉的临时空间

(1)计算bubblesort的空间复杂度
java 复制代码
void bubbleSort(int[] array) {
        for (int end = array.length; end > 0; end--) {
            boolean sorted = true;
            for (int i = 1; i < end; i++) {
                if (array[i - 1] > array[i]) {
                    Swap(array, i - 1, i);
                    sorted = false;
                }
            }
            if (sorted == true) {
                break;
            }
        }
    }

上述代码中,临时变量有int end,boolean sorted,int i,设数组元素为N,sorted与i都是创建了N次,但是都是销毁了前一个,才创建下一个,前一个与下一个都共用了同一个空间,实际上空间只需要固定3份。空间复杂度为O(1)

(2)计算fibonacci的空间复杂度
java 复制代码
    int[] fibonacci(int n) {
        long[] fibArray = new long[n + 1];
        fibArray[0] = 0;
        fibArray[1] = 1;
        for (int i = 2; i <= n ; i++) {
            fibArray[i] = fibArray[i - 1] + fibArray [i - 2];
        }
        return fibArray;
    }

代码中的临时变量有long[] fibArray,int i,总共的空间为n+1+2,空间复杂度为O(n)。

(3)计算fibonacci的空间复杂度
java 复制代码
int fibonacci(int N) {
        return N < 2 ? N : fibonacci(N-1)+fibonacci(N-2);
    }

代码中递归调用了N次,开辟了N个栈帧,空间复杂度为O(N)

相关推荐
yaoxin5211232 小时前
324. Java Stream API - 实现 Collector 接口:自定义你的流式收集器
java·windows·python
米羊1212 小时前
Struts 2 漏洞(上)
java·后端·struts
訫悦2 小时前
C++自带的set get语法(MSVC)
开发语言·c++
SmartBrain2 小时前
Python 特性(第一部分):知识点讲解(含示例)
开发语言·人工智能·python·算法
galaxyffang2 小时前
Java堆内存诊断:从工具使用到实战分析
java·jvm
01二进制代码漫游日记2 小时前
自定义类型:联合和枚举(一)
c语言·开发语言·学习·算法
SmartBrain3 小时前
FastAPI进阶(第一部分):路由和依赖特性(含考题)
开发语言·python
小学卷王3 小时前
复试day25
算法
样例过了就是过了3 小时前
LeetCode热题100 和为 K 的子数组
数据结构·算法·leetcode