常用的数据结构:数组、链表、堆、栈、队列、哈希表、树和图
数组(Array)
定义
数组是一种线性数据结构,用于存储固定数量的相同类型元素。数组中的元素在内存中是连续存储的,可以通过索引直接访问。
特点
- 存储方式:元素在内存中连续存储。
- 访问方式:通过索引直接访问,时间复杂度为O(1)。
- 插入和删除:需要移动大量元素,时间复杂度为O(n)。
- 存储空间:利用率高,没有额外空间开销。
- 适用场景:需要频繁随机访问数据元素的场景。
操作
- 访问元素:通过索引直接访问。
- 插入元素:需要移动后面的元素。
- 删除元素:需要移动后面的元素。
- 更新元素:通过索引直接更新。
- 获取长度:通过数组的长度属性。
示例代码(java)
int[] array = {1, 2, 3, 4, 5};
int value = array[2]; // 访问索引为2的元素
array[2] = 10; // 更新索引为2的元素
链表(Linked List)
定义
链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
特点
- 存储方式:元素可以存储在不连续的存储空间中,通过指针链接。
- 访问方式:通过指针逐个访问,时间复杂度为O(n)。
- 插入和删除:只需修改指针,时间复杂度为O(1)。
- 存储空间:利用率较低,需要额外空间存储指针。
- 适用场景:需要频繁插入和删除数据元素的场景。
操作
- 访问元素:从头节点开始逐个访问。
- 插入元素:修改指针,无需移动元素。
- 删除元素:修改指针,无需移动元素。
- 更新元素:通过指针找到节点后更新数据部分。
示例代码(java)
class Node {
int data;
Node next;
Node(int data) {
this.data = data;
this.next = null;
}
}
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
堆(Heap)
定义
堆是一种非线性数据结构,通常实现为二叉堆。堆是一种完全二叉树,满足堆属性(最大堆或最小堆)。
特点
- 存储方式:通常使用数组实现,逻辑上是一个完全二叉树。
- 访问方式:通过索引访问,时间复杂度为O(1)。
- 插入和删除:插入和删除操作的时间复杂度为O(log n)。
- 存储空间:利用率高,没有额外空间开销。
- 适用场景:需要高效获取最大值或最小值的优先级队列场景。
操作
- 插入元素:将元素插入堆中并调整堆结构。
- 删除元素:删除根节点并调整堆结构。
- 获取最大/最小值:直接访问根节点。
示例代码(java)
import java.util.PriorityQueue;
PriorityQueue<Integer> heap = new PriorityQueue<>();
heap.add(1);
heap.add(2);
heap.add(3);
heap.poll(); // 返回1
栈(Stack)
定义
栈是一种后进先出(LIFO)的数据结构,只能通过栈顶进行插入和删除操作。
特点
- 存储方式:可以使用数组或链表实现。
- 访问方式:通过栈顶访问,时间复杂度为O(1)。
- 插入和删除:插入和删除操作的时间复杂度为O(1)。
- 存储空间:利用率高,没有额外空间开销。
- 适用场景:函数调用、表达式求值等场景。
操作
- 插入元素:将元素压入栈顶。
- 删除元素:从栈顶弹出元素。
- 访问元素:访问栈顶元素。
示例代码(java)
import java.util.Stack;
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.pop(); // 返回2
队列(Queue)
定义
队列是一种先进先出(FIFO)的数据结构,用于存储待处理的任务。
特点
- 存储方式:可以使用数组或链表实现。
- 访问方式:通过队头访问,时间复杂度为O(1)。
- 插入和删除:插入和删除操作的时间复杂度为O(1)。
- 存储空间:利用率高,没有额外空间开销。
- 适用场景:操作系统、网络协议和并发编程等领域。
操作
- 插入元素:将元素加入队尾。
- 删除元素:从队头移除元素。
- 访问元素:访问队头元素。
示例代码(java)
import java.util.LinkedList;
import java.util.Queue;
Queue<Integer> queue = new LinkedList<>();
queue.add(1);
queue.add(2);
queue.poll(); // 返回1
哈希表(Hash Table)
定义
哈希表是一种非线性数据结构,通过哈希函数将键映射到存储位置。
特点
- 存储方式:通过哈希函数计算存储位置,解决冲突的方法包括开放定址法和链地址法。
- 访问方式:通过哈希函数直接访问,平均时间复杂度为O(1)。
- 插入和删除:通过哈希函数直接操作,平均时间复杂度为O(1)。
- 存储空间:利用率取决于哈希函数和表的大小,可能存在空间浪费。
- 适用场景:需要快速查找、插入和删除数据元素的场景。
操作
- 查找元素:通过哈希函数计算位置。
- 插入元素:通过哈希函数计算位置并插入。
- 删除元素:通过哈希函数计算位置并删除。
- 更新元素:找到位置后更新数据部分。
示例代码 (java)
import java.util.HashMap;
HashMap<Integer, String> map = new HashMap<>();
map.put(1, "Alice");
map.put(2, "Bob");
String value = map.get(1); // 访问键为1的元素
map.put(1, "Charlie"); // 更新键为1的元素
map.remove(2); // 删除键为2的元素
树(Tree)
定义
树是一种非线性数据结构,由节点组成,每个节点可以有多个子节点。树的顶部节点称为根节点,其他节点称为子节点。
特点
- 存储方式:节点通过指针或引用链接,形成层次结构。
- 访问方式:通过递归或队列进行遍历,时间复杂度为O(n)。
- 插入和删除:操作复杂度取决于树的类型和平衡性。
- 存储空间:利用率较低,需要额外空间存储指针。
- 适用场景:需要表示层次关系或进行快速查找的场景。
操作
- 访问元素:通过递归或队列进行遍历。
- 插入元素:根据树的类型(如二叉搜索树)进行插入。
- 删除元素:根据树的类型进行删除,可能需要调整树的结构。
- 更新元素:找到节点后更新数据部分。
示例代码(java)
class TreeNode {
int data;
TreeNode left;
TreeNode right;
TreeNode(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
图(Graph)
定义
图是一种非线性数据结构,由节点(顶点)和边组成。图可以是有向图或无向图。
特点
- 存储方式:节点通过指针或引用链接,形成复杂的网络结构。
- 访问方式:通过递归或队列进行遍历,时间复杂度为O(n)。
- 插入和删除:操作复杂度取决于图的类型和结构。
- 存储空间:利用率较低,需要额外空间存储指针。
- 适用场景:社交网络、交通网络和网页链接等。
操作
- 添加节点和边:通过指针或引用链接节点。
- 查找路径和最短路径:通过图的遍历算法(如深度优先搜索和广度优先搜索)。
- 遍历图:通过递归或队列进行遍历。
示例代码(java)
import java.util.*;
class Graph {
private Map<Integer, List<Integer>> adjList;
public Graph() {
adjList = new HashMap<>();
}
public void addEdge(int src, int dest) {
adjList.computeIfAbsent(src, k -> new ArrayList<>()).add(dest);
adjList.computeIfAbsent(dest, k -> new ArrayList<>()).add(src);
}
public void printGraph() {
for (Map.Entry<Integer, List<Integer>> entry : adjList.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
Graph graph = new Graph();
graph.addEdge(1, 2);
graph.addEdge(1, 3);
graph.addEdge(2, 3);
graph.printGraph();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库