📜  数据结构和算法 | 37套(1)

📅  最后修改于: 2023-12-03 15:40:01.661000             🧑  作者: Mango

数据结构和算法 | 37套

此合集中包含了37个数据结构和算法的复习/练习/面试题集合,涵盖了从基础的数组、链表、栈、队列、树等数据结构到高级的动态规划、图算法等内容。适合于打算进入IT行业的学生、准备进行算法竞赛的选手以及正在找工作的程序员进行复习和练习。

数据结构介绍(Data Structures)
数组(Array)

数组是一种保存固定长度的线性数据结构。它由一些连续的内存地址组成,每个地址对应一个元素。在Java和Python中,数组长度可以动态改变。

示例代码:

int[] arr = {1, 2, 3};
System.out.println(arr[0]); // 1
arr = [1, 2, 3]
print(arr[0]) # 1
链表(Linked List)

链表是一种使用指针连接在一起的数据结构,每个节点都包含一个数据以及指向下一个节点的指针。链表有单向链表和双向链表两种形式。

示例代码:

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(3);
node1.next = node2;
node2.next = node3;
System.out.println(node1.next.val); // 2
class ListNode:
    def __init__(self, val):
        self.val = val
        self.next = None

node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node1.next = node2
node2.next = node3
print(node1.next.val) # 2
栈(Stack)

栈是一种后进先出(LIFO)的数据结构。对栈只能进行两种操作,即入栈(push)和出栈(pop)。

示例代码:

Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop()); // 3
stack = []
stack.append(1)
stack.append(2)
stack.append(3)
print(stack.pop()) # 3
队列(Queue)

队列是一种先进先出(FIFO)的数据结构。队列有循环队列和双端队列两种形式。

示例代码:

Queue<Integer> queue = new LinkedList<>();
queue.offer(1);
queue.offer(2);
queue.offer(3);
System.out.println(queue.poll()); // 1
from collections import deque

queue = deque()
queue.append(1)
queue.append(2)
queue.append(3)
print(queue.popleft()) # 1
树(Tree)

树是一种层次结构的数据结构,它由节点和边组成。树的根节点没有父节点,其他节点最多有一个父节点和多个子节点。

示例代码:

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

TreeNode root = new TreeNode(1);
TreeNode left = new TreeNode(2);
TreeNode right = new TreeNode(3);
root.left = left;
root.right = right;
System.out.println(root.right.val); // 3
class TreeNode:
    def __init__(self, val):
        self.val = val
        self.left = None
        self.right = None

root = TreeNode(1)
left = TreeNode(2)
right = TreeNode(3)
root.left = left
root.right = right
print(root.right.val) # 3
算法介绍(Algorithms)
排序算法(Sorting)

排序算法是将一组数据按照特定的顺序进行排列的算法。常见的排序算法有快速排序、归并排序、插入排序、选择排序等。

示例代码:

int[] nums = {3, 2, 1};
Arrays.sort(nums); // 快速排序
System.out.println(Arrays.toString(nums)); // [1, 2, 3]
nums = [3, 2, 1]
nums.sort() # 快速排序
print(nums) # [1, 2, 3]
查找算法(Searching)

查找算法是在数据集合中寻找特定元素的算法。常见的查找算法有二分查找、线性查找等。

示例代码:

int[] nums = {1, 2, 3};
int index = Arrays.binarySearch(nums, 2); // 二分查找
System.out.println(index); // 1
nums = [1, 2, 3]
index = nums.index(2) # 线性查找
print(index) # 1
字符串算法(String)

字符串算法是处理文本字符串的一类算法。常见的字符串算法有正则表达式、KMP算法、BM算法等。

示例代码:

String str = "hello, world";
System.out.println(str.indexOf("world")); // 7
str = "hello, world"
print(str.index("world")) # 7
动态规划(Dynamic Programming)

动态规划是将复杂问题分解成小问题来求解的算法。它通常用于求解具有重复子问题的优化问题。

示例代码:

int n = 5;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
    dp[i] = dp[i-1] + dp[i-2];
}
System.out.println(dp[n]); // 5
n = 5
dp = [0] * (n+1)
dp[0] = 0
dp[1] = 1
for i in range(2, n+1):
    dp[i] = dp[i-1] + dp[i-2]
print(dp[n]) # 5
图算法(Graph)

图算法是用于解决图论问题的一类算法。常见的图算法有最短路径算法、最小生成树算法、拓扑排序等。

示例代码:

int[][] graph = { { 0, 1, 1, 0 },
                  { 1, 0, 1, 1 },
                  { 1, 1, 0, 1 },
                  { 0, 1, 1, 0 } };
int n = graph.length;

// Floyd算法
for (int k = 0; k < n; k++) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (graph[i][k] != 0 && graph[k][j] != 0 && (graph[i][j] == 0 || graph[i][j] > graph[i][k] + graph[k][j]))
                graph[i][j] = graph[i][k] + graph[k][j];
        }
    }
}

System.out.println(Arrays.deepToString(graph)); // [[0, 1, 1, 2], [1, 0, 1, 1], [1, 1, 0, 1], [2, 1, 1, 0]]
graph = [[0, 1, 1, 0],
         [1, 0, 1, 1],
         [1, 1, 0, 1],
         [0, 1, 1, 0]]
n = len(graph)

# Floyd算法
for k in range(n):
    for i in range(n):
        for j in range(n):
            if graph[i][k] != 0 and graph[k][j] != 0 and (graph[i][j] == 0 or graph[i][j] > graph[i][k] + graph[k][j]):
                graph[i][j] = graph[i][k] + graph[k][j]

print(graph) # [[0, 1, 1, 2], [1, 0, 1, 1], [1, 1, 0, 1], [2, 1, 1, 0]]