数据结构

数据结构与算法

10个数据结构:数组、链表、栈、队列、散列表、二叉树、堆、调表、图、Trie 树

10个算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法

1.什么是数据结构

定义 操作系统中组织数据的集合

1.1 逻辑数据结构

反映数据元素之间的逻辑关系,与数据在计算机中存储的位置无关

形式:集合、线性、树形、图

1.2 物理数据结构

逻辑数据在计算机真正存储的形式

形式:1)顺序存储 --数组:数据元素放在地址连续的空间中,数据的逻辑关系与物理关系一致

​ 优点:方便进行随机元素的查找,查找速度快(下标);

​ 缺点:数组的插入与删除操作很耗时,需要频繁的进行元素的移动,比较浪费内存空间

​ 2)不连续存储–链表:元素存储在随机单元中,可以是连续的,也可以是不连续的

​ (类比排队 只知前后的元素,对其他的不清楚,第一个节点一定知道第二个节点,但不知道第三个)

​ 优点:方便进行元素的插入与删除(若删除第三个元素,只需将第二个元素指向第四个元素);

​ 缺点:元素查找速度慢,只能从前向后遍历(若需要找特定元素需从头遍历),节省空间

总结: 频繁查找用数组,频繁插入删除用链表、内存紧张用链表

计算机组成原理

内存:高速存储 CPU直接管理工作站:128G 读写速率高于磁盘先将数据读取到内存中,数据用完后清除出去,再读取新的数据

外存:硬盘 磁盘:PB C盘

内存:100MB 连续空间:可用连续空间70MB

要储存71MB,采用数组:一个元素也放不下(连续空间不足) 若采用链式存储:能存储70MB空间元素

2. 什么是算法

**定义:**算法是在特定的数据结构上一组输入按照特定的方式输出。是良好的计算过程,是解决问题求解的步骤。

如何衡量一个算法的优缺点?

以空间换时间

从两个角度:时间上;空间上;

3.时间复杂度

时间复杂度:衡量一个算法的运行速度,时间效率;

3.1 评判方法:

事后统计法:把代码跑一遍,通过统计、监测等手段就能得到算法执行时间和占用内存大小

​ 缺点:1)测试结果非常依赖测试环境

​ 2)测试结果受数据影响很大

3.2 大O时间复杂度方法

所有代码的执行时间T(n)与每行代码的执行次数 n 成正比:T(n)=O( f ( n ) );当n足够大只需计算最大量级;

大O时间复杂度实际上并不具体表示代码的真正执行时间,而是表示代码执行时间随数据规模度增长的变化趋势,所以也叫作 渐进时间复杂度,简称时间复杂度

分析方法

  1. 只关心循环次数最多的代码(代码中只有一个循环体时);
  2. 加法法则:总复杂度等于量级最大的那段代码的复杂度(代码中有多个循环体);
  3. 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
3.2.1多项式时间复杂度: O(1)、O(n)、O(log n)、O(O^2)

O(1):常数级时间复杂度 只要代码不随n增长变化,都属于O(1)常数级复杂度;

O(n):

O(n^2):

for(int i=0;i<n;i++){//看自变量有没有参与运算
    for(int j=0;j<i;j++){
        
    }
}

O(m+n):与m、n、趋势有关,由于m与n的数据规模不定,因此使用加法法则保留两者的复杂度。

int cal(int m,int n){
    int sum_1=0;
    int i=i;
    for(;i < m;i++){//只有当这个循环的规模也不确定时,两个复杂度都保留
       sum_i = sum_i+1;
    }
    int sum_2 = 0;
    int j = 1;
    for(; j < n; ++j){
       sum_2 = sum_2 + j;
     }
    return sum_1 + sum_2;
}

O(log n):对数时间复杂度 :任意底数的对数都可以换成以2为底

O(nlogn):快速排序、归并排序、

for(int i=0;i<n;i++){//两层循环
    while(i<=n){
        i=i*2;
    }
}
3.2.2非多项式时间复杂度:O(2^n) 、O( n! )

复杂度量级分为两类:当n越来越大时,非多项式的时间复杂度急剧增加,因此非多项式的算法基本不用。

3.3 最好、最坏、平均时间复杂度
//n表示数组array的长度
int find(int[] array, int n, int x) { 
     int i = 0;  int pos = -1;  
     for (; i < n; ++i) {    
         if (array[i] == x)
             pos = i; 
     }  
     return pos; 
 }
//这个代码的时间复杂度为O(n);
//优化后代码
int find(int[] array, int n, int x) { 
     int i = 0;  int pos = -1;  
     for (; i < n; ++i) {    
         if (array[i] == x){
             pos = i; 
             break}
     }  
     return pos; 
 }
//代码时间复杂度
//最好情况:第一个元素即为所要查找元素  O(1)
//最坏情况:最后一个元素为所要查找元素  O(n)
//平均情况: 有n+1中情况               O(n)

在这里插入图片描述

时间复杂度排序:O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)

4.空间复杂度:

代码所占用的空间所需内存大小

S(n)=O(f(n));

public static int sun(int n){
    int count =0;
    for(int i=1;i<=n;i++){
        count +=i;
    }
    retuen count;
}
//上述代码空间复杂度是:O(1) 

另:

public class Test{
    public static void main(String[] args){
        fun();
    }
    public static void fun(){
        fun();
    }
}

上述程序出现:栈溢出异常:

在这里插入图片描述

这个异常属于非受查异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值