在學習計算機時,數據結構是不可忽視的一點,從考研時的408課程,再到工作中編寫軟件,網站,要想在計算機領域站住腳跟,數據結構是必備的
在這里,我對于數據結構進行了匯總,并簡要描述,在后面會對各種數據結構進行詳細介紹
在 Java 中,數據結構主要分為兩大類:線性數據結構 和 非線性數據結構。Java 標準庫(如 java.util
包)提供了許多現成的數據結構實現,這些實現基于不同的底層存儲方式和操作特性。以下是對 Java 中常見數據結構的詳細描述:
1. 線性數據結構
線性數據結構是指數據元素之間存在一對一的線性關系。
(1)數組(Array)
數組是一種基本的線性數據結構,用于存儲固定大小的同類型數據元素。
-
特點:
-
元素存儲在連續的內存空間中。
-
支持隨機訪問,通過索引可以快速訪問任意位置的元素,時間復雜度為 O(1)。
-
插入和刪除操作效率較低,通常需要移動大量元素,時間復雜度為 O(n)。
-
數組的大小在創建后不可變。
-
-
示例代碼:
-
int[] array = new int[10]; array[0] = 1; array[1] = 2; System.out.println(array[0]); // 輸出:1
(2)動態數組(ArrayList)
ArrayList
是 Java 中基于動態數組實現的集合類,它提供了動態擴容的功能。
-
特點:
-
底層使用數組存儲元素。
-
支持隨機訪問,時間復雜度為 O(1)。
-
插入和刪除操作效率較低,時間復雜度為 O(n)。
-
動態擴容,可以根據需要自動調整數組大小。
-
-
示例代碼:
-
import java.util.ArrayList;public class Main {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);System.out.println(list.get(0)); // 輸出:1list.remove(0);System.out.println(list.get(0)); // 輸出:2} }
(3)鏈表(LinkedList)
LinkedList
是 Java 中基于雙向鏈表實現的集合類,它支持高效的插入和刪除操作。
-
特點:
-
底層使用雙向鏈表存儲元素。
-
不支持隨機訪問,訪問任意位置的元素需要從頭開始遍歷,時間復雜度為 O(n)。
-
插入和刪除操作效率較高,時間復雜度為 O(1)。
-
適合頻繁插入和刪除操作的場景。
-
-
示例代碼:
-
import java.util.LinkedList;public class Main {public static void main(String[] args) {LinkedList<Integer> list = new LinkedList<>();list.add(1);list.add(2);System.out.println(list.get(0)); // 輸出:1list.remove(0);System.out.println(list.get(0)); // 輸出:2} }
(4)棧(Stack)
棧是一種后進先出(LIFO)的數據結構,Java 提供了 Stack
類來實現棧。
-
特點:
-
支持快速的插入和刪除操作,時間復雜度為 O(1)。
-
只能在棧頂進行插入和刪除操作。
-
適合實現函數調用、表達式求值等場景。
-
-
示例代碼:
-
import java.util.Stack;public class Main {public static void main(String[] args) {Stack<Integer> stack = new Stack<>();stack.push(1);stack.push(2);System.out.println(stack.pop()); // 輸出:2System.out.println(stack.pop()); // 輸出:1} }
(5)隊列(Queue)
隊列是一種先進先出(FIFO)的數據結構,Java 提供了 Queue
接口和多種實現類(如 LinkedList
、ArrayDeque
等)。
-
特點:
-
支持快速的插入和刪除操作,時間復雜度為 O(1)。
-
只能在隊尾插入元素,在隊頭刪除元素。
-
適合實現任務調度、消息隊列等場景。
-
-
示例代碼:
-
import java.util.LinkedList; import java.util.Queue;public class Main {public static void main(String[] args) {Queue<Integer> queue = new LinkedList<>();queue.add(1);queue.add(2);System.out.println(queue.poll()); // 輸出:1System.out.println(queue.poll()); // 輸出:2} }
2. 非線性數據結構
非線性數據結構是指數據元素之間存在多對多的關系。
(1)樹(Tree)
樹是一種層次化的數據結構,每個節點可以有多個子節點。
-
常見類型:
-
二叉樹(Binary Tree):每個節點最多有兩個子節點。
-
二叉搜索樹(Binary Search Tree):左子樹的所有節點值小于根節點值,右子樹的所有節點值大于根節點值。
-
平衡二叉樹(Balanced Binary Tree):左右子樹的高度差不超過 1。
-
紅黑樹(Red-Black Tree):一種自平衡的二叉搜索樹。
-
堆(Heap):一種特殊的完全二叉樹,分為最大堆和最小堆。
-
-
示例代碼(二叉樹):
-
class TreeNode {int val;TreeNode left;TreeNode right;TreeNode(int x) {val = x;} }public class Main {public static void main(String[] args) {TreeNode root = new TreeNode(1);root.left = new TreeNode(2);root.right = new TreeNode(3);} }
(2)圖(Graph)
圖是一種由節點(頂點)和邊組成的復雜數據結構,節點之間可以存在任意關系。
-
特點:
-
節點之間通過邊連接,可以是有向邊或無向邊。
-
支持復雜的遍歷和搜索算法,如深度優先搜索(DFS)和廣度優先搜索(BFS)。
-
適合表示復雜的關系網絡,如社交網絡、地圖路徑等。
-
-
示例代碼(無向圖):
-
import java.util.ArrayList; import java.util.List;class Graph {private int vertices;private List<List<Integer>> adjacencyList;public Graph(int vertices) {this.vertices = vertices;this.adjacencyList = new ArrayList<>();for (int i = 0; i < vertices; i++) {adjacencyList.add(new ArrayList<>());}}public void addEdge(int src, int dest) {adjacencyList.get(src).add(dest);adjacencyList.get(dest).add(src); // 無向圖}public void printGraph() {for (int i = 0; i < vertices; i++) {System.out.println("Adjacency list of vertex " + i);System.out.print("head");for (int j : adjacencyList.get(i)) {System.out.print(" -> " + j);}System.out.println();}} }public class Main {public static void main(String[] args) {Graph graph = new Graph(5);graph.addEdge(0, 1);graph.addEdge(0, 4);graph.addEdge(1, 2);graph.addEdge(1, 3);graph.addEdge(1, 4);graph.addEdge(2, 3);graph.addEdge(3, 4);graph.printGraph();} }
(3)哈希表(Hash Table)
哈希表是一種通過哈希函數將鍵映射到值的數據結構。
-
特點:
-
提供快速的插入、刪除和查找操作,平均時間復雜度為 O(1)。
-
哈希函數將鍵映射到存儲位置,可能存在沖突,需要解決沖突的方法(如鏈表法、開放尋址法)。
-
適合實現字典、緩存等場景。
-
-
示例代碼:
-
import java.util.HashMap;public class Main {public static void main(String[] args) {HashMap<String, Integer> map = new HashMap<>();map.put("Alice", 25);map.put("Bob", 30);System.out.println(map.get("Alice")); // 輸出:25map.remove("Bob");} }