13.5 排序与查找
面试重要程度:⭐⭐⭐⭐⭐
常见提问方式: "手写快速排序" "实现二分查找" "分析排序算法复杂度"
预计阅读时间:45分钟
🔄 经典排序算法
基础排序算法
/**
* 基础排序算法实现
*/
public class BasicSortingAlgorithms {
/**
* 冒泡排序
* 时间复杂度:O(n²),空间复杂度:O(1)
* 稳定排序
*/
public void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
boolean swapped = false;
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
swapped = true;
}
}
// 如果没有发生交换,说明已经有序
if (!swapped) break;
}
}
/**
* 选择排序
* 时间复杂度:O(n²),空间复杂度:O(1)
* 不稳定排序
*/
public 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;
}
}
// 交换最小元素到当前位置
if (minIndex != i) {
swap(arr, i, minIndex);
}
}
}
/**
* 插入排序
* 时间复杂度:O(n²),空间复杂度:O(1)
* 稳定排序
*/
public 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;
}
}
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
高效排序算法
/**
* 高效排序算法实现
*/
public class AdvancedSortingAlgorithms {
/**
* 快速排序
* 平均时间复杂度:O(n log n),最坏:O(n²)
* 空间复杂度:O(log n),不稳定排序
*/
public void quickSort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
private void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}
private int partition(int[] arr, int low, int high) {
int pivot = arr[high]; // 选择最后一个元素作为基准
int i = low - 1; // 小于基准的元素的索引
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
/**
* 归并排序
* 时间复杂度:O(n log n),空间复杂度:O(n)
* 稳定排序
*/
public void mergeSort(int[] arr) {
if (arr.length <= 1) return;
int[] temp = new int[arr.length];
mergeSort(arr, temp, 0, arr.length - 1);
}
private void mergeSort(int[] arr, int[] temp, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, temp, left, mid);
mergeSort(arr, temp, mid + 1, right);
merge(arr, temp, left, mid, right);
}
}
private void merge(int[] arr, int[] temp, int left, int mid, int right) {
// 复制到临时数组
for (int i = left; i <= right; i++) {
temp[i] = arr[i];
}
int i = left, j = mid + 1, k = left;
// 合并两个有序子数组
while (i <= mid && j <= right) {
if (temp[i] <= temp[j]) {
arr[k++] = temp[i++];
} else {
arr[k++] = temp[j++];
}
}
// 复制剩余元素
while (i <= mid) {
arr[k++] = temp[i++];
}
while (j <= right) {
arr[k++] = temp[j++];
}
}
/**
* 堆排序
* 时间复杂度:O(n log n),空间复杂度:O(1)
* 不稳定排序
*/
public void heapSort(int[] arr) {
int n = arr.length;
// 构建最大堆
for (int i = n / 2 - 1; i >= 0; i--) {
heapify(arr, n, i);
}
// 逐个提取元素
for (int i = n - 1; i > 0; i--) {
swap(arr, 0, i); // 将最大元素移到末尾
heapify(arr, i, 0); // 重新调整堆
}
}
private void heapify(int[] arr, int n, int i) {
int largest = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && arr[left] > arr[largest]) {
largest = left;
}
if (right < n && arr[right]
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
Java面试圣经 文章被收录于专栏
Java面试圣经,带你练透java圣经
查看5道真题和解析