数据结构与算法之概念

allenxx / 2023-09-01 / 原文

1. 数据结构

 

存储、组织数据的方式 包括数组、链表、堆、栈、队列、树、图等

同样的数据不同的组织方式就是数据结构。比如对老王的姓名、年龄、性别的描述:

  列表方式:[老王,18,男]
  字典方式:{name:"老王",age:18,sex:"男"}

而列表、字典存储了老外的数据并按照不同的方式存储在内存中。

 

 

分类

1. 线性结构:线性结构中的数据元素之间存在一对一的关系,即每个元素只有一个直接前驱和一个直接后继。常见的线性结构包括数组、链表、栈和队列等。

  • 数组(Array):一组具有相同类型的元素按照一定顺序排列,并通过索引访问。
  • 链表(Linked List):一组节点按照顺序连接而成的数据结构,每个节点包含数据和指向下一个节点的指针。
  • 栈(Stack):一种具有特殊操作限制的线性表,按照“先进后出”的原则进行插入和删除操作。
  • 队列(Queue):一种具有特殊操作限制的线性表,“先进先出”的原则进行插入和删除操作。

2. 树形结构:树形结构中的数据元素之间存在一对多的关系,即每个元素有且仅有一个直接前驱,但可以有多个直接后继。常见的树形结构包括二叉树、堆和哈夫曼树等。

  • 二叉树(Binary Tree):每个节点最多有两个子节点的树结构。
  • 堆(Heap):一种特殊的二叉树,每个节点的值都大于或小于其子节点的值,用于实现优先队列等应用。
  • 哈夫曼树(Huffman Tree):通过频率来构建的一种特殊二叉树,常被用于数据压缩。

3. 图形结构:图形结构中的数据元素之间存在多对多的关系,即每个元素可以与其他任意元素有关联。常见的图形结构包括有向图和无向图等。

  • 有向图(Directed Graph):图中的边具有方向性。
  • 无向图(Undirected Graph):图中的边没有方向性。

4. 散列结构:散列结构利用散列函数将数据元素映射到一个固定位置,常用于实现哈希表等。

以上只是数据结构的一些常见分类,实际上还有很多其他类型的数据结构,如集合、链表、树堆、图等。不同的数据结构适用于不同的场景和问题,选择合适的数据结构可以提高算法效率和程序性能。

 

1.1 数组

一组连续存储的相同类型元素的集合。连续存储说的是内存空间的使用情况,表示是一块连续内存空间。访问可以根据索引访问

1.2 链表

由节点组成的线性数据结构,每个节点包含数据和指向下一个节点的指针。在内存空间的表现是不连续,通过指针建立前后关系

 

1.3 堆

 

在计算机科学中,"堆"(Heap)是一种用于动态内存分配的数据结构。堆用于存储程序运行时分配和释放的数据,例如对象、函数的局部变量等。

它与栈(Stack)不同,栈用于存储函数调用的上下文和局部变量。

堆是一块大的内存区域,它的大小在程序运行时可以动态地增长或缩小,允许程序在需要时动态地分配内存。

在堆中分配的内存块通常由程序员手动分配和释放(java有垃圾回收机制),这需要一些管理工作以避免内存泄漏和悬挂指针等问题。

 

在堆中,数据存储的方式不是按照线性顺序,而是以一种更为灵活的方式进行组织。

对象和数据结构可以在堆中的不同位置分布,而且它们的大小不需要事先确定。这使得堆成为动态内存分配的理想选择,特别是在需要存储不同大小和不同生命周期的数据时。

值得注意的是,堆不仅仅用于动态内存分配,还用于存储在程序运行期间需要长时间存在的数据,如全局变量和动态分配的对象。

不同的编程语言和操作系统对于堆的管理方式可能会有所不同。

1.4 栈

一种后进先出(LIFO)的数据结构,只允许在栈顶进行插入和删除操作。或者说先进后出

 

1.5 队列

 一种先进先出的数据结构。

队列(Queue)遵循先进先出(First-In-First-Out,FIFO)的原则。在队列中,首先被添加到队列的元素也将首先被移除,类似于排队等候的概念。

 

队列有两个主要操作:入队(Enqueue)和出队(Dequeue)。入队操作将元素添加到队列的尾部,出队操作将队列的头部元素移除并返回。

队列常常用于模拟排队等待的场景,例如打印任务队列、计算机进程调度等。在编程中,队列的应用非常广泛,它可以帮助我们有效地管理和操作一系列数据。

 

1.6 树结构

 

 

 

1.7 图结构

 

有向图

 

无向图

 

1.8 哈希表

 

 

2.  数据类型

JAVA

Java常见的数据类型

 

  1. 列表、集合、字典/map都是以类存在的
  2. Java是编译解释语言,也是强类型语言、静态类型语言
  3. 对于数据结构来说这些数据都可以存储。有1点特别注意:数组结构也可以存储数组这种数据(就是绕了点,说白了就是数组中的元素是数组)

 

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        Object [] array = new Object[2];
        array[0]=new int[]{1,2,3};
        array[1]=new int[]{3,4,5};
        System.out.println(Arrays.toString((int[]) array[0]));
        System.out.println(Arrays.toString((int[]) array[1]));
    }
}

 输出:

[1, 2, 3]
[3, 4, 5]

  

 

Python

 

1. 因为Python一切皆对象,只能按可变、不可变来区分。

2. Python 中的一切都被视为对象。这是 Python 的一项基本设计原则,被称为 "一切皆对象"("everything is an object")原则。

3. 在 Python 中,不仅是变量、数据类型和函数,连数字、字符串、类、模块等各种概念都被视为对象。

4. 这种对象的概念意味着每个对象都有一些数据(称为属性)和可以在对象上执行的操作(称为方法)。

5. 这也意味着你可以在 Python 中将对象作为参数传递、将它们分配给变量,并且在运行时操作它们的属性和方法。

6. 类、函数、模块也可视为不可变类型

https://aistudio.baidu.com/projectdetail/5408513

JavaScript

 

 

 

js与Python一样是动态语言即变量的类型可以在运行时根据值的类型自动更改(弱语言)。

变量的类型可以在运行时自动推断或改变

 

 

 

算法

解决问题的具体步骤或计算过程。 包括排序算法(如冒泡排序、插入排序、选择排序、快速排序、归并排序)、搜索算法(如线性搜索、二分搜索、广度优先搜索、深度优先搜索)等。

分治法

 

递归法

 

贪心法

 

动态规划法

 

迭代法

 

枚举法

 

回溯法

 

算法的衡量标准

 

复杂度分析:用来评估算法执行效率的指标,包括时间复杂度和空间复杂度。

在数据量不断增加的前提下,执行时间、内存占用的变化趋势,来衡量算法优劣。

时间复杂度

表示算法执行时间随输入规模增长的变化趋势。

 

空间复杂度

表示算法所需内存空间随输入规模增长的变化趋势。

 

应用

 

排序

 

查找

 

加解密

 

计算