1. 排序算法
冒泡排序(Bubble Sort)
重复比较相邻元素,将大的元素 "冒泡" 到末尾
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n-1; i++) {
// 每轮循环后,最大的元素已"冒泡"到末尾
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
// 交换元素
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
// 使用示例
int[] arr = {64, 34, 25, 12, 22, 11, 90};
bubbleSort(arr);
System.out.println(Arrays.toString(arr)); // [11, 12, 22, 25, 34, 64, 90]
选择排序(Selection Sort)
每次从剩余元素中找到最小元素,放到已排序序列的末尾
public static void selectionSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n-1; i++) {
// 找到最小元素的索引
int minIndex = i;
for (int j = i+1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// 交换找到的最小元素和当前元素
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
插入排序(Insertion Sort)
将元素逐个插入到已排序的序列中
public static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
// 将大于key的元素向后移动
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
归并排序(Merge Sort)
采用分治法,将数组分成两半分别排序,再合并
public static void mergeSort(int[] arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
// 递归排序两半
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
// 合并已排序的两半
merge(arr, left, mid, right);
}
}
private static void merge(int[] arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
// 创建临时数组
int[] L = new int[n1];
int[] R = new int[n2];
// 复制数据到临时数组
System.arraycopy(arr, left, L, 0, n1);
System.arraycopy(arr, mid + 1, R, 0, n2);
// 合并临时数组
int i = 0, j = 0;
int k = left;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}
// 复制剩余元素
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}
}
2. 查找算法
线性查找(Linear Search)
逐个检查每个元素直到找到目标
public static int linearSearch(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i; // 返回找到的索引
}
}
return -1; // 未找到
}
// 使用示例
int[] arr = {10, 20, 30, 40, 50};
int target = 30;
int result = linearSearch(arr, target);
System.out.println(result); // 2
二分查找(Binary Search)
在有序数组中,每次将搜索范围减半
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止溢出
if (arr[mid] == target) {
return mid; // 找到目标,返回索引
}
if (arr[mid] < target) {
left = mid + 1; // 目标在右半部分
} else {
right = mid - 1; // 目标在左半部分
}
}
return -1; // 未找到
}
3. 图算法
深度优先搜索(DFS)
import java.util.*;
public class GraphDFS {
private int V; // 顶点数量
private LinkedList<Integer> adj[]; // 邻接表
// 构造函数
GraphDFS(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList();
}
// 添加边
void addEdge(int v, int w) {
adj[v].add(w);
}
// DFS函数
void DFSUtil(int v, boolean visited[]) {
// 标记当前节点为已访问并打印
visited[v] = true;
System.out.print(v + " ");
// 递归访问所有未访问的邻接节点
Iterator<Integer> i = adj[v].listIterator();
while (i.hasNext()) {
int n = i.next();
if (!visited[n])
DFSUtil(n, visited);
}
}
// 主DFS函数
void DFS(int v) {
// 标记所有节点为未访问
boolean visited[] = new boolean[V];
// 调用递归辅助函数
DFSUtil(v, visited);
}
// 使用示例
public static void main(String args[]) {
GraphDFS g = new GraphDFS(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
System.out.println("从顶点2开始的DFS遍历:");
g.DFS(2); // 输出: 2 0 1 3
}
}
广度优先搜索(BFS)
import java.util.*;
public class GraphBFS {
private int V;
private LinkedList<Integer> adj[];
GraphBFS(int v) {
V = v;
adj = new LinkedList[v];
for (int i = 0; i < v; ++i)
adj[i] = new LinkedList();
}
void addEdge(int v, int w) {
adj[v].add(w);
}
// BFS函数
void BFS(int s) {
// 标记所有节点为未访问
boolean visited[] = new boolean[V];
// 创建队列
LinkedList<Integer> queue = new LinkedList<Integer>();
// 标记当前节点为已访问并加入队列
visited[s] = true;
queue.add(s);
while (queue.size() != 0) {
// 出队并打印
s = queue.poll();
System.out.print(s + " ");
// 获取所有邻接节点
Iterator<Integer> i = adj[s].listIterator();
while (i.hasNext()) {
int n = i.next();
if (!visited[n]) {
visited[n] = true;
queue.add(n);
}
}
}
}
public static void main(String args[]) {
GraphBFS g = new GraphBFS(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
System.out.println("从顶点2开始的BFS遍历:");
g.BFS(2); // 输出: 2 0 3 1
}
}
4. 动态规划算法
斐波那契数列(非递归实现)
public static int fibonacci(int n) {
if (n <= 1)
return n;
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];
}
return dp[n];
}
// 使用示例
System.out.println(fibonacci(10)); // 55
最长公共子序列(LCS)
public static String lcs(String str1, String str2) {
int m = str1.length();
int n = str2.length();
// 创建DP表
int[][] dp = new int[m + 1][n + 1];
// 填充DP表
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
// 回溯构建LCS
int i = m, j = n;
StringBuilder sb = new StringBuilder();
while (i > 0 && j > 0) {
if (str1.charAt(i - 1) == str2.charAt(j - 1)) {
sb.append(str1.charAt(i - 1));
i--;
j--;
} else if (dp[i - 1][j] > dp[i][j - 1]) {
i--;
} else {
j--;
}
}
return sb.reverse().toString();
}
// 使用示例
String str1 = "ABCBDAB";
String str2 = "BDCAB";
System.out.println(lcs(str1, str2)); // "BCAB"
5. 字符串算法
KMP 算法(字符串匹配)
public class KMPAlgorithm {
// 构建部分匹配表
private static int[] computeLPS(String pattern) {
int n = pattern.length();
int[] lps = new int[n];
int len = 0; // 最长前缀后缀的长度
for (int i = 1; i < n; ) {
if (pattern.charAt(i) == pattern.charAt(len)) {
len++;
lps[i] = len;
i++;
} else {
if (len != 0) {
len = lps[len - 1];
} else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
// KMP搜索算法
public static int kmpSearch(String text, String pattern) {
int m = text.length();
int n = pattern.length();
if (n == 0) return 0;
if (m < n) return -1;
int[] lps = computeLPS(pattern);
int i = 0; // 文本索引
int j = 0; // 模式索引
while (i < m) {
if (pattern.charAt(j) == text.charAt(i)) {
i++;
j++;
if (j == n) {
return i - j; // 找到匹配,返回起始索引
}
} else {
if (j != 0) {
j = lps[j - 1];
} else {
i++;
}
}
}
return -1; // 未找到匹配
}
// 使用示例
public static void main(String[] args) {
String text = "ABABDABACDABABCABAB";
String pattern = "ABABCABAB";
int result = kmpSearch(text, pattern);
System.out.println(result); // 10
}
}
6. 贪心算法
活动选择问题
import java.util.*;
public class ActivitySelection {
static class Activity {
int start, end;
Activity(int s, int e) {
start = s;
end = e;
}
}
// 选择最大数量的非重叠活动
public static void selectActivities(Activity[] activities) {
// 按结束时间排序
Arrays.sort(activities, Comparator.comparingInt(a -> a.end));
System.out.println("选中的活动:");
int lastEnd = -1;
for (Activity activity : activities) {
if (activity.start >= lastEnd) {
System.out.println("(" + activity.start + ", " + activity.end + ")");
lastEnd = activity.end;
}
}
}
public static void main(String[] args) {
Activity[] activities = {
new Activity(1, 4),
new Activity(3, 5),
new Activity(0, 6),
new Activity(5, 7),
new Activity(3, 9),
new Activity(5, 9),
new Activity(6, 10),
new Activity(8, 11),
new Activity(8, 12),
new Activity(2, 14),
new Activity(12, 16)
};
selectActivities(activities);
// 输出选中的活动,它们是按结束时间最早排序的非重叠活动
}
}
2330

被折叠的 条评论
为什么被折叠?



