常见数据结构及Java实现

1. 数组 (Array)

数组是一种线性数据结构,元素在内存中连续存储,支持快速随机访问。访问元素的时间复杂度为O(1)O(1)O(1),但插入和删除可能需要O(n)O(n)O(n)时间(需移动元素)。

public class ArrayExample {
    public static void main(String[] args) {
        // 声明并初始化整型数组
        int[] arr = {1, 2, 3, 4, 5};
        
        // 访问元素(索引从0开始)
        System.out.println("第三个元素: " + arr[2]); // 输出 3
        
        // 修改元素
        arr[2] = 10;
        System.out.println("修改后第三个元素: " + arr[2]); // 输出 10
        
        // 遍历数组
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        // 输出: 1 2 10 4 5
    }
}
2. 链表 (Linked List)

链表由节点组成,每个节点包含数据和指向下一个节点的指针。插入和删除头节点的时间复杂度为O(1)O(1)O(1),但随机访问需要O(n)O(n)O(n)时间。链表适合动态大小数据。

// 定义链表节点类
class ListNode {
    int val;
    ListNode next;
    ListNode(int val) {
        this.val = val;
        this.next = null;
    }
}

// 链表操作示例
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 newNode = new ListNode(0);
        newNode.next = head;
        head = newNode; // 链表变为: 0 -> 1 -> 2 -> 3
        
        // 删除头节点
        head = head.next; // 链表变为: 1 -> 2 -> 3
        
        // 遍历链表
        ListNode current = head;
        while (current != null) {
            System.out.print(current.val + " ");
            current = current.next;
        }
        // 输出: 1 2 3
    }
}
3. 栈 (Stack)

栈是一种后进先出(LIFO)结构,只允许在栈顶进行插入(push)和删除(pop)操作。push和pop的时间复杂度均为O(1)O(1)O(1)。栈常用于函数调用和表达式求值。

import java.util.Stack; // 使用Java标准库

public class StackExample {
    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<>();
        
        // 压栈操作
        stack.push(10);
        stack.push(20);
        stack.push(30); // 栈状态: [10, 20, 30] (30在栈顶)
        
        // 弹栈操作
        System.out.println("弹出元素: " + stack.pop()); // 输出 30
        System.out.println("当前栈顶: " + stack.peek()); // 输出 20
        
        // 检查栈是否为空
        System.out.println("栈是否为空? " + stack.isEmpty()); // 输出 false
    }
}
4. 队列 (Queue)

队列是一种先进先出(FIFO)结构,元素从队尾入队(enqueue),从队头出队(dequeue)。enqueue和dequeue的时间复杂度通常为O(1)O(1)O(1)。队列适用于任务调度。

import java.util.LinkedList;
import java.util.Queue; // 使用Java标准库

public class QueueExample {
    public static void main(String[] args) {
        Queue<Integer> queue = new LinkedList<>();
        
        // 入队操作
        queue.add(10);
        queue.add(20);
        queue.add(30); // 队列状态: [10, 20, 30] (10在队头)
        
        // 出队操作
        System.out.println("出队元素: " + queue.poll()); // 输出 10
        System.out.println("当前队头: " + queue.peek()); // 输出 20
        
        // 检查队列是否为空
        System.out.println("队列是否为空? " + queue.isEmpty()); // 输出 false
    }
}
5. 二叉树 (Binary Tree)

二叉树每个节点最多有两个子节点(左和右)。插入、删除和搜索的时间复杂度在平衡树中为O(log⁡n)O(\log n)O(logn),最坏情况下为O(n)O(n)O(n)。二叉树用于高效搜索和排序。

// 定义二叉树节点类
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int val) {
        this.val = val;
        this.left = null;
        this.right = null;
    }
}

// 二叉树操作示例
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);
        
        // 插入新节点 (作为左子节点的左子节点)
        root.left.left = new TreeNode(4);
        
        // 前序遍历: 根 -> 左 -> 右
        System.out.print("前序遍历: ");
        preOrderTraversal(root); // 输出: 1 2 4 3
    }
    
    // 前序遍历辅助方法
    public static void preOrderTraversal(TreeNode node) {
        if (node == null) return;
        System.out.print(node.val + " ");
        preOrderTraversal(node.left);
        preOrderTraversal(node.right);
    }
}
6. 哈希表 (Hash Table)

哈希表使用哈希函数将键映射到存储位置,支持快速插入、删除和查找。平均时间复杂度为O(1)O(1)O(1),但哈希冲突时可能退化到O(n)O(n)O(n)。哈希表适用于键值对存储。

import java.util.HashMap; // 使用Java标准库

public class HashTableExample {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<>();
        
        // 插入键值对
        map.put("apple", 10);
        map.put("banana", 20);
        map.put("orange", 30);
        
        // 查找值
        System.out.println("apple的数量: " + map.get("apple")); // 输出 10
        
        // 删除键
        map.remove("banana");
        System.out.println("banana是否存在? " + map.containsKey("banana")); // 输出 false
        
        // 遍历所有键值对
        for (String key : map.keySet()) {
            System.out.println(key + ": " + map.get(key));
        }
        // 输出: apple: 10, orange: 30
    }
}

总结

以上数据结构覆盖了常见场景:

  • 数组:适合快速访问,但大小固定。
  • 链表:动态大小,插入删除高效。
  • 栈和队列:管理数据顺序,分别用于LIFO和FIFO场景。
  • 二叉树:高效搜索和排序基础。
  • 哈希表:快速键值查找。

在实际应用中,Java标准库(如ArrayListLinkedListHashMap)提供了优化实现。建议根据需求选择合适结构,例如搜索用树结构,缓存用哈希表。复杂度分析有助于预测性能,如平均查找时间在哈希表中为O(1)O(1)O(1),在二叉搜索树中为O(log⁡n)O(\log n)O(logn)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值