数据结构

63 阅读4分钟

以下是常见数据结构的详细解释及Java示例代码,结合了知识库中的核心概念和实现细节:


1. 数组(Array)

特点

  • 线性结构,内存连续,固定大小。
  • 优点:快速随机访问(O(1))。
  • 缺点:插入/删除效率低(O(n))。

Java示例

public class ArrayExample {
    public static void main(String[] args) {
        // 定义数组
        int[] arr = {1, 2, 3, 4, 5};
        
        // 访问元素
        System.out.println("元素 2 的值:" + arr[1]); // 输出 2
        
        // 遍历数组
        for (int num : arr) {
            System.out.print(num + " "); // 输出 1 2 3 4 5
        }
    }
}

2. 链表(Linked List)

特点

  • 线性结构,动态大小,非连续内存。
  • 优点:插入/删除高效(O(1)时间,但需找到位置)。
  • 缺点:无法随机访问,需遍历查找。

Java示例(自定义单链表):

class ListNode {
    int val;
    ListNode next;
    ListNode(int val) { this.val = val; }
}

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建链表:1 -> 2 -> 3
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        
        // 遍历链表
        ListNode current = head;
        while (current != null) {
            System.out.print(current.val + " "); // 输出 1 2 3
            current = current.next;
        }
    }
}

3. 栈(Stack)

特点

  • 线性结构,后进先出(LIFO)。
  • Java实现:使用Deque接口(推荐)或Stack类。

Java示例

import java.util.Deque;
import java.util.ArrayDeque;

public class StackExample {
    public static void main(String[] args) {
        Deque<Integer> stack = new ArrayDeque<>();
        
        stack.push(1); // 入栈
        stack.push(2);
        stack.push(3);
        
        System.out.println("栈顶元素:" + stack.peek()); // 输出 3
        
        while (!stack.isEmpty()) {
            System.out.print(stack.pop() + " "); // 输出 3 2 1(出栈顺序)
        }
    }
}

4. 队列(Queue)

特点

  • 线性结构,先进先出(FIFO)。
  • Java实现:使用Queue接口(如LinkedListArrayDeque)。

Java示例

import java.util.Queue;
import java.util.LinkedList;

public class QueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        
        queue.offer(1); // 入队
        queue.offer(2);
        queue.offer(3);
        
        System.out.println("队列头部元素:" + queue.peek()); // 输出 1
        
        while (!queue.isEmpty()) {
            System.out.print(queue.poll() + " "); // 输出 1 2 3(出队顺序)
        }
    }
}

5. 哈希表(Hash Table)

特点

  • 非线性结构,通过键值对(Key-Value)存储。
  • 优点:平均O(1)的增删改查。
  • Java实现HashMap(基于数组+链表/红黑树)。

Java示例

import java.util.HashMap;

public class HashMapExample {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        
        map.put("Alice", 25); // 添加键值对
        map.put("Bob", 30);
        
        System.out.println("Alice的年龄:" + map.get("Alice")); // 输出 25
        
        map.remove("Bob"); // 删除键
        
        System.out.println("哈希表大小:" + map.size()); // 输出 1
    }
}

6. 二叉树(Binary Tree)

特点

  • 非线性结构,每个节点最多有两个子节点(左、右)。
  • Java实现:自定义节点类。

Java示例(简单二叉树结构):

class TreeNode {
    int val;
    TreeNode left, right;
    TreeNode(int val) { this.val = val; }
}

public class BinaryTreeExample {
    public static void main(String[] args) {
        // 创建二叉树:
        //      1
        //    /   \
        //   2     3
        TreeNode root = new TreeNode(1);
        root.left = new TreeNode(2);
        root.right = new TreeNode(3);
        
        // 遍历根节点的左右子节点
        System.out.println("根节点:" + root.val);
        System.out.println("左子节点:" + root.left.val);
        System.out.println("右子节点:" + root.right.val);
    }
}

7. 堆(Heap)

特点

  • 完全二叉树结构,满足堆性质(最大堆/最小堆)。
  • Java实现PriorityQueue(默认最小堆)。

Java示例

import java.util.PriorityQueue;

public class HeapExample {
    public static void main(String[] args) {
        // 最小堆示例
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        minHeap.add(3);
        minHeap.add(1);
        minHeap.add(2);
        
        System.out.println("堆顶元素:" + minHeap.peek()); // 输出 1
        
        while (!minHeap.isEmpty()) {
            System.out.print(minHeap.poll() + " "); // 输出 1 2 3(按顺序弹出)
        }
    }
}

8. 图(Graph)

特点

  • 非线性结构,由节点(顶点)和边组成。
  • Java实现:邻接表(常用)。

Java示例(无向图邻接表):

import java.util.*;

class Graph {
    private int vertices;
    private LinkedList<Integer>[] adjList;
    
    public Graph(int vertices) {
        this.vertices = vertices;
        adjList = new LinkedList[vertices];
        for (int i = 0; i < vertices; i++) {
            adjList[i] = new LinkedList<>();
        }
    }
    
    public void addEdge(int src, int dest) {
        adjList[src].add(dest);
        adjList[dest].add(src); // 无向图需双向添加
    }
    
    public void printGraph() {
        for (int v = 0; v < vertices; v++) {
            System.out.print("顶点 " + v + " 的邻接点:");
            for (int neighbor : adjList[v]) {
                System.out.print(neighbor + " ");
            }
            System.out.println();
        }
    }
}

public class GraphExample {
    public static void main(String[] args) {
        Graph graph = new Graph(4);
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(2, 3);
        
        graph.printGraph();
        // 输出:
        // 顶点 0 的邻接点:1 2 
        // 顶点 1 的邻接点:0 3 
        // 顶点 2 的邻接点:0 3 
        // 顶点 3 的邻接点:1 2 
    }
}

总结对比

结构特点Java实现类适用场景
数组固定大小,随机访问快int[], ArrayList频繁访问已知索引的场景
链表动态大小,插入/删除高效LinkedList频繁插入/删除的场景
后进先出(LIFO)Deque(推荐)递归、表达式求值
队列先进先出(FIFO)LinkedList, ArrayDeque消息队列、任务调度
哈希表快速查找/插入/删除HashMap, TreeMap唯一键值对存储(如缓存)
二叉树层次化结构,高效查找自定义节点类文件系统、搜索算法(如BST)
优先级队列PriorityQueue调度任务(如Dijkstra算法)
复杂关系建模邻接表/邻接矩阵社交网络、路径规划(如Dijkstra)

选择建议

  • 随机访问 → 数组/ArrayList。
  • 频繁插入/删除 → 链表/LinkedList。
  • 键值对快速查找 → 哈希表(HashMap)。
  • 优先级操作 → 堆(PriorityQueue)。
  • 复杂关系建模 → 图(邻接表)。

通过结合场景需求和数据结构特性,可以高效选择合适的结构!