“好读书,不求甚解;每有会意,便欣然忘食。”
文章目录
- 前言
- 文章有误敬请斧正 不胜感恩!
- 1.数组(Array)
- 2. 链表(Linked List)
- 3. 栈(Stack)
- 4. 队列(Queue)
- 5. 哈希表(HashMap)
- 6. 二叉树(Binary Tree)
- 7.栈 (Stack)
- 8. 堆 (Heap)
- 9. 图 (Graph)
- 10. 广义表 (Generalized List)
- 总结
前言
提示:以下是本篇文章正文内容
Hello大家好
今天给大家带来常用的数据结构Java代码实现。
市面上主流的数据结构教程都是以C语言为主,在用Java学习数据结构的过程中,
书上给的代码要么过于冗余,要么不够全面,因此我总结了一些常用的数据结构的操作,可以作为模板来使用。
在平常的使用中也能更加便捷.
那么我们话不多说,一起来看看今天的代码.
文章有误敬请斧正 不胜感恩!
1.数组(Array)
数组是一个固定大小的集合,所有元素类型相同,通过索引访问元素。
public class ArrayExample {
public static void main(String[] args) {
// 定义一个整数数组并初始化
int[] numbers = {10, 20, 30, 40, 50};
// 访问数组中索引为2的元素(第三个元素)
System.out.println("Element at index 2: " + numbers[2]); // 输出 30
// 修改索引为2的元素
numbers[2] = 35;
System.out.println("Updated element at index 2: " + numbers[2]); // 输出 35
}
}
2. 链表(Linked List)
链表由节点组成,每个节点包含数据和指向下一个节点的引用。
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
// 创建一个空的链表
LinkedList<String> list = new LinkedList<>();
// 添加元素到链表的末尾
list.add("A");
list.add("B");
list.add("C");
// 在索引1的位置插入元素
list.add(1, "D");
// 访问链表中的第一个元素
System.out.println("First element: " + list.get(0)); // 输出 A
// 从链表中删除元素"B"
list.remove("B");
System.out.println("List after removal: " + list); // 输出 [A, D, C]
}
}
3. 栈(Stack)
栈是后进先出(LIFO)的数据结构,常用于函数调用、撤销操作等。
import java.util.Stack;
public class StackExample {
public static void main(String[] args) {
// 创建一个空的栈
Stack<Integer> stack = new Stack<>();
// 将元素压入栈中
stack.push(10);
stack.push(20);
stack.push(30);
// 查看栈顶元素,不移除它
System.out.println("Top element: " + stack.peek()); // 输出 30
// 移除并返回栈顶元素
System.out.println("Popped element: " + stack.pop()); // 输出 30
// 查看栈中剩余的元素
System.out.println("Stack after pop: " + stack); // 输出 [10, 20]
}
}
4. 队列(Queue)
队列是先进先出(FIFO)的数据结构,常用于任务调度、数据缓冲等。
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
// 使用LinkedList实现队列
Queue<String> queue = new LinkedList<>();
// 向队列添加元素
queue.add("A");
queue.add("B");
queue.add("C");
// 查看队首元素,但不移除它
System.out.println("Head element: " + queue.peek()); // 输出 A
// 移除并返回队首元素
System.out.println("Removed element: " + queue.remove()); // 输出 A
// 查看队列中剩余的元素
System.out.println("Queue after removal: " + queue); // 输出 [B, C]
}
}
5. 哈希表(HashMap)
哈希表通过键值对存储数据,可以高效地插入、删除和查找。
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
// 创建一个空的HashMap
HashMap<String, Integer> map = new HashMap<>();
// 向HashMap中添加键值对
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
// 通过键访问值
System.out.println("Value for key 'Banana': " + map.get("Banana")); // 输出 2
// 移除键为"Apple"的键值对
map.remove("Apple");
System.out.println("Map after removal: " + map); // 输出 {Banana=2, Cherry=3}
}
}
6. 二叉树(Binary Tree)
二叉树是一种分层数据结构,常用于表示具有层次关系的数据,如文件系统、表达式树等。
// 定义二叉树的节点类
class TreeNode {
int value; // 节点的值
TreeNode left, right; // 左右子节点的引用
// 构造函数,用于创建新节点
public TreeNode(int item) {
value = item;
left = right = null; // 初始时没有子节点
}
}
// 定义二叉树类
class BinaryTree {
TreeNode root; // 根节点
// 前序遍历(先访问根节点,然后是左子树,最后是右子树)
void preOrder(TreeNode node) {
if (node == null) {
return; // 如果当前节点为空,结束递归
}
// 访问当前节点
System.out.print(node.value + " ");
// 递归遍历左子树
preOrder(node.left);
// 递归遍历右子树
preOrder(node.right);
}
public static void main(String[] args) {
// 创建一个二叉树
BinaryTree tree = new BinaryTree();
// 初始化节点
tree.root = new TreeNode(1); // 根节点
tree.root.left = new TreeNode(2); // 根的左子节点
tree.root.right = new TreeNode(3); // 根的右子节点
tree.root.left.left = new TreeNode(4); // 根左子节点的左子节点
tree.root.left.right = new TreeNode(5); // 根左子节点的右子节点
// 前序遍历二叉树
System.out.print("Preorder traversal: ");
tree.preOrder(tree.root); // 输出 1 2 4 5 3
}
}
7.栈 (Stack)
概念: 栈是一种遵循“后进先出” (LIFO) 原则的线性数据结构,常用于表达式求值、括号匹配等场景。
实现: 栈可以使用数组或链表实现,Java中也有Stack类,但我们可以自己实现一个简单的栈。
// 栈的数组实现
class Stack {
private int maxSize;
private int[] stackArray;
private int top;
public Stack(int size) {
this.maxSize = size;
this.stackArray = new int[maxSize];
this.top = -1;
}
// 入栈
public void push(int value) {
if (isFull()) {
System.out.println("栈已满,无法插入元素");
return;
}
stackArray[++top] = value;
}
// 出栈
public int pop() {
if (isEmpty()) {
System.out.println("栈为空,无法弹出元素");
return -1;
}
return stackArray[top--];
}
// 查看栈顶元素
public int peek() {
if (isEmpty()) {
System.out.println("栈为空,无法查看元素");
return -1;
}
return stackArray[top];
}
// 判断栈是否为空
public boolean isEmpty() {
return (top == -1);
}
// 判断栈是否已满
public boolean isFull() {
return (top == maxSize - 1);
}
}
常见操作: push()、pop()、peek(),时间复杂度均为O(1)。
8. 堆 (Heap)
概念: 堆是一种特殊的树形结构,分为最大堆和最小堆,常用于优先队列、排序等。
实现: 堆通常用数组实现,我们以最小堆为例。
// 最小堆实现
class MinHeap {
private int[] heap;
private int size;
private int maxSize;
public MinHeap(int maxSize) {
this.maxSize = maxSize;
this.size = 0;
this.heap = new int[this.maxSize + 1];
heap[0] = Integer.MIN_VALUE;
}
// 获取父节点索引
private int parent(int pos) {
return pos / 2;
}
// 获取左子节点索引
private int leftChild(int pos) {
return (2 * pos);
}
// 获取右子节点索引
private int rightChild(int pos) {
return (2 * pos) + 1;
}
// 判断是否是叶子节点
private boolean isLeaf(int pos) {
return pos > (size / 2) && pos <= size;
}
// 交换两个节点
private void swap(int fpos, int spos) {
int tmp = heap[fpos];
heap[fpos] = heap[spos];
heap[spos] = tmp;
}
// 向下堆化
private void minHeapify(int pos) {
if (!isLeaf(pos)) {
if (heap[pos] > heap[leftChild(pos)] || heap[pos] > heap[rightChild(pos)]) {
if (heap[leftChild(pos)] < heap[rightChild(pos)]) {
swap(pos, leftChild(pos));
minHeapify(leftChild(pos));
} else {
swap(pos, rightChild(pos));
minHeapify(rightChild(pos));
}
}
}
}
// 插入元素
public void insert(int element) {
if (size >= maxSize) {
return;
}
heap[++size] = element;
int current = size;
while (heap[current] < heap[parent(current)]) {
swap(current, parent(current));
current = parent(current);
}
}
// 移除堆顶元素
public int remove() {
int popped = heap[1];
heap[1] = heap[size--];
minHeapify(1);
return popped;
}
}
常见操作: 插入insert()和删除remove(),时间复杂度为O(log n)。
9. 图 (Graph)
概念: 图是一种复杂的数据结构,由节点和边组成,可分为有向图和无向图。
实现: 使用邻接表实现图,邻接表可以用HashMap和List实现。
// 图的邻接表实现
import java.util.*;
class Graph {
private Map<Integer, List<Integer>> adjList;
public Graph() {
adjList = new HashMap<>();
}
// 添加节点
public void addVertex(int vertex) {
adjList.putIfAbsent(vertex, new ArrayList<>());
}
// 添加边
public void addEdge(int source, int destination) {
adjList.get(source).add(destination);
adjList.get(destination).add(source); // 对于无向图
}
// 移除边
public void removeEdge(int source, int destination) {
List<Integer> eV = adjList.get(source);
List<Integer> eD = adjList.get(destination);
if (eV != null) eV.remove(Integer.valueOf(destination));
if (eD != null) eD.remove(Integer.valueOf(source));
}
// 移除节点
public void removeVertex(int vertex) {
adjList.values().forEach(e -> e.remove(Integer.valueOf(vertex)));
adjList.remove(vertex);
}
// 显示图
public void printGraph() {
for (var entry : adjList.entrySet()) {
System.out.println("节点 " + entry.getKey() + " 连接到 " + entry.getValue());
}
}
```java
}
常见操作: 添加节点addVertex()、添加边addEdge()、删除边removeEdge(),时间复杂度取决于具体实现。
10. 广义表 (Generalized List)
概念: 广义表是一种包含多层次元素的表结构,常用于表达复杂的嵌套关系。
实现: Java中没有直接的广义表类,可以通过递归定义节点来实现。
// 广义表节点定义
class GListNode {
boolean isAtom; // 是否为原子
int value; // 原子值
GListNode next; // 下一个节点
GListNode subList; // 子表
// 原子节点
public GListNode(int value) {
this.isAtom = true;
this.value = value;
this.next = null;
this.subList = null;
}
// 表节点
public GListNode(GListNode subList) {
this.isAtom = false;
this.subList = subList;
this.next = null;
}
}
// 广义表实现
class GeneralizedList {
private GListNode head;
// 构造函数
public GeneralizedList() {
head = null;
}
// 打印广义表
public void printList(GListNode node) {
if (node == null) return;
if (node.isAtom) {
System.out.print(node.value + " ");
} else {
System.out.print("( ");
printList(node.subList);
System.out.print(") ");
}
printList(node.next);
}
}
常见操作: 插入节点、遍历打印等,时间复杂度取决于广义表的嵌套深度。
总结
OK今天的代码分享就到这里了,我们明天再见!