常用的数据结构:数组、链表、堆、栈、队列、哈希表、树和图

数组(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();
posted @   抒写  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示