数据结构和算法中的基本常识

简介: 数据结构和算法中的基本常识

公众号merlinsea


  • 什么是数据结构
  • 数据结构指的是数据相互之间的一种或者多种特定的关系数据元素集合。通俗一点就是说,计算机对数据进行存储时候并不是杂乱没有顺序的,而是具有一定的规则,一个或者多个的数据元素之间就一定拥有一定的关系,所以说数据结构是计算机的存储和组织数据的方式。


  • 什么是算法
  • 算法是针对底层特点的数据结构设计出来的求解问题的步骤就对于程序而言,算法就是程序的灵魂,优秀的算法可以在面对大量数据计算时,依旧能够保持高速的计算。但是如果对数据量大的程序,我们就需要对时间和空间有要有效的利用,也就是设计一个高效的算法,在同样的硬件设备的情况下,有时候会把速度提高十倍甚至上百倍。


  • 程序 = 数据结构 + 算法
  • 在计算机里来说,如果把单独的数据结构和算法拿出来讨论其实意义不大,就像鱼离不开水,算法也离不开数据结构。如果数据之间没有任何结构的话,算法也就无法实现了,毫无意义了。当然即使数据之间有关系,但是不基于这些数据针对特定的问题设计出特定的解题步骤(即算法),那么这些数据的组织方式也毫无意义

  • 总之:数据结构和算法必须要针对特定的问题场景做特定的设计,没有万能的数据结构,也没有万能的算法。


  • 算法的时间复杂度
  • 时间复杂度是用于评价算法执行快慢的一个指标,如果一个算法的时间复杂度越高,那么这个算法执行相同规模问题所花费的时间也越多。
  • 时间复杂度并不是算法从开始运行到结束运行所花费的时间,而是指这个算法完成这个问题所需要执行的基本操作的总次数。我们会用这个中次数来衡量我们的时间复杂度。


  • 判断一个算法的时间复杂度的方式
  1. 确定问题的规模n,对于任意一个问题都会有一个问题的规模n,比如找扑克牌的问题,我们的输入数据是54张扑克牌,那么问题的规模n=54。
  2. 确定算法所需要执行的基本操作有哪些? 比如找扑克牌问题中,基本操作其实就是遍历每一张牌看牌的操作。
  3. 确定实际执行基本操作的次数 和 问题规模n 的函数关系   即求出f(n)
  4. 确定f(n)的函数数量级的上限O(n),最终O(n)就是算法的时间复杂度。


  • 举例子


void fun(int n){
  int i,j,x=0;
  for(i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      x++;
    }
  }
}
void fun(int n){
  int i = 0;
  i++;
}


  1. 问题的规模是入参n
  2. 执行的基本操作是x++
  3. 实际执行次数 f(n)= n-1 + n-2 + n-3 + ...+ 0 = n(n-1)/2 = n*n/2-n/2
  4. f(n)数量级的上限是O(n^2)


640.png


  • 常见的时间复杂度数量级排序
  • O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(n^k)<O(2^n),可以看出随着规模n的不断变大,执行的效率就越低。


640.png

  • 时间复杂度的优化方向
  • 如果我们计算出来的时间复杂度是O(n^2),那么我们必须要将时间复杂度优化到O(nlogn)级别。


  • 算法的空间复杂度
  • 如果我们有一个数组,如何我们需要对这个数组进行排序我们改如何做呢?


640.png640.png


  • 第一种方法:新开一个空间,每次都将数组排序以后放在新的内存空间中


//空间复杂度是O(n)
int[] sortArray(int[] nums) {
    int[] tempNums = new int[nums.length];//零时辅助数组
    for(int i=0;i<nums.length;i++){
      int idx = 0;//新的零时数组中下标的位置
      for(int j=0;j<=nums.length;j++){
        if(nums[j]<=nums[i]){
          idx++;
        }
      }
      // idx 结果表示原数组中有多少个元素比nums[i]更小
      tempNums[idx]=nums[i];
    }
    //倒回去
    for(int i=0;i<nums.length;i++){
      nums[i] = tempNums[i];
    }
    return nums;
}


  • 第二种方法:不新开一个空间,在原始数组的空间中完成排序操作


//空间复杂度是O(1)
void sortArray(int[] nums){
    for(int i=0;i<nums.length;i++){
        int k = i;
        for(int j=i;j<nums.length();j++){
            if(nums[j]<nums[k]){
                k = j;
            }
        }
      // 保证下标k的位置是最小的
        swap(nums[i],nums[k]); //交换
    }
}


  • 空间复杂度
  • 空间复杂度是指我们程序在完成指定功能的过程中,需要额外开辟的空间,如果程序中涉及的额外空间与问题规模n无关,那么空间复杂度就是O(1)常数级别,如果设计的空间复杂度与n是相关,比如第一中排序方法,那么就是O(n)。
  • 在实际的开发过程中,我们很少考虑空间复杂度,因为现代的存储设备已经远远可以满足我们日常开发需要,一般我们都会利用空间来换时间,即宁可花更多的空间也要减少程序的时间开销,动态规划
目录
打赏
0
0
1
0
297
分享
相关文章
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构
K-means聚类算法是机器学习中常用的一种聚类方法,通过将数据集划分为K个簇来简化数据结构。本文介绍了K-means算法的基本原理,包括初始化、数据点分配与簇中心更新等步骤,以及如何在Python中实现该算法,最后讨论了其优缺点及应用场景。
261 6
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
148 1
|
1月前
|
算法系列之数据结构-二叉树
树是一种重要的非线性数据结构,广泛应用于各种算法和应用中。本文介绍了树的基本概念、常见类型(如二叉树、满二叉树、完全二叉树、平衡二叉树、B树等)及其在Java中的实现。通过递归方法实现了二叉树的前序、中序、后序和层次遍历,并展示了具体的代码示例和运行结果。掌握树结构有助于提高编程能力,优化算法设计。
48 9
 算法系列之数据结构-二叉树
|
28天前
|
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
42 3
 算法系列之数据结构-Huffman树
|
30天前
|
算法系列之数据结构-二叉搜索树
二叉查找树(Binary Search Tree,简称BST)是一种常用的数据结构,它能够高效地进行查找、插入和删除操作。二叉查找树的特点是,对于树中的每个节点,其左子树中的所有节点都小于该节点,而右子树中的所有节点都大于该节点。
69 22
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
102 29
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
130 25
C 408—《数据结构》算法题基础篇—数组(通俗易懂)
408考研——《数据结构》算法题基础篇之数组。(408算法题的入门)
87 23
探索局域网电脑监控软件:Python算法与数据结构的巧妙结合
在数字化时代,局域网电脑监控软件成为企业管理和IT运维的重要工具,确保数据安全和网络稳定。本文探讨其背后的关键技术——Python中的算法与数据结构,如字典用于高效存储设备信息,以及数据收集、异常检测和聚合算法提升监控效率。通过Python代码示例,展示了如何实现基本监控功能,帮助读者理解其工作原理并激发技术兴趣。
98 20
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
81 2

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等