您的位置:首页 > 游戏 > 手游 > 排序算法解析:从基础到高级

排序算法解析:从基础到高级

2024/11/16 23:50:09 来源:https://blog.csdn.net/shippingxing/article/details/139248082  浏览:    关键词:排序算法解析:从基础到高级

排序算法是计算机科学中一个至关重要的概念,无论是在数据结构、数据库管理还是机器学习领域,排序算法都扮演着不可或缺的角色。本专栏旨在为读者提供一个全面的排序算法解析,从基础到高级,帮助读者深入理解排序算法的原理、实现以及应用。

第一部分:排序算法基础

1. 排序算法简介

排序算法是将一组数据按照特定的顺序重新排列的算法。它们可以根据不同的性能指标进行分类,如时间复杂度、空间复杂度和稳定性。

2. 基本概念

排序算法可以分为比较排序和非比较排序,以及原地排序和非原地排序。每种分类都有其特定的应用场景和优势。

3. 基本排序算法

以下是一些基本排序算法的Java实现:

冒泡排序
public class BubbleSort {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]) {// Swap arr[j] and arr[j+1]int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}
}
选择排序
public class SelectionSort {public static void selectionSort(int[] arr) {int n = arr.length;for (int i = 0; i < n - 1; i++) {// Find the minimum element in unsorted arrayint minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// Swap the found minimum element with the first elementint temp = arr[minIndex];arr[minIndex] = arr[i];arr[i] = temp;}}
}
插入排序
public class InsertionSort {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;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j = j - 1;}arr[j + 1] = key;}}
}

第二部分:中级排序算法

1. 归并排序

public class MergeSort {void merge(int arr[], int l, int m, int r) {int n1 = m - l + 1;int n2 = r - m;int L[] = new int[n1];int R[] = new int[n2];for (int i = 0; i < n1; ++i)L[i] = arr[l + i];for (int j = 0; j < n2; ++j)R[j] = arr[m + 1 + j];int i = 0, j = 0;int k = l;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++;}}void sort(int arr[], int l, int r) {if (l < r) {int m = (l + r) / 2;sort(arr, l, m);sort(arr, m + 1, r);merge(arr, l, m, r);}}
}

2. 快速排序

public class QuickSort {void sort(int[] arr, int low, int high) {if (low < high) {int pi = partition(arr, low, high);sort(arr, low, pi - 1);sort(arr, pi + 1, high);}}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++;int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}

3. 堆排序

public class HeapSort {void heapify(int[] arr, int n, int i) {int largest = i;int l = 2 * i + 1;int r = 2 * i + 2;if (l < n && arr[l] > arr[largest])largest = l;if (r < n && arr[r] > arr[largest])largest = r;if (largest != i) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;heapify(arr, n, largest);}}void sort(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--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;heapify(arr, i, 0);}}
}

第三部分:高级排序算法

1. 希尔排序

public class ShellSort {void shellSort(int[] arr) {int n = arr.length;int gap = n / 2;while (gap > 0) {for (int i = gap; i < n; i++) {int temp = arr[i];int j;for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}gap /= 2;}}
}

2. 计数排序

public class CountingSort {void countingSort(int[] arr, int max) {int[] output = new int[arr.length];int[] count = new int[max + 1];for (int i = 0; i < arr.length; i++)count[arr[i]]++;for (int i = 1; i <= max; i++)count[i] += count[i - 1];for (int i = arr.length - 1; i >= 0; i--) {output[count[arr[i]] - 1] = arr[i];count[arr[i]]--;}for (int i = 0; i < arr.length; i++)arr[i] = output[i];}
}

3. 桶排序

public class BucketSort {void bucketSort(float[] arr) {int n = arr.length;int i;float[] b = new float[n];for (i = 0; i < n; ++i) {b[i] = arr[i];}float min = b[0];float max = b[0];for (i = 1; i < n; ++i) {if (b[i] < min) {min = b[i];} else if (b[i] > max) {max = b[i];}}float range = (max - min) / n;int[] count = new int[n];for (i = 0; i < n; i++) {count[((int) ((b[i] - min) / range))]++;}for (i = 1; i < n; i++) {count[i] += count[i - 1];}float[] sortedArray = new float[n];for (i = n - 1; i >= 0; i--) {sortedArray[count[((int) ((b[i] - min) / range)) - 1] - 1] = b[i];count[((int) ((b[i] - min) / range))]--;}for (i = 0; i < n; i++) {arr[i] = sortedArray[i];}}
}

4. 基数排序

public class RadixSort {void radixSort(int[] arr) {int max = getMax(arr);for (int exp = 1; max / exp > 0; exp *= 10) {countSort(arr, exp);}}int getMax(int[] arr) {int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] > max)max = arr[i];}return max;}void countSort(int[] arr, int exp) {int n = arr.length;int[] output = new int[n];int[] count = new int[10];for (int i = 0; i < n; i++) {count[(arr[i] / exp) % 10]++;}for (int i = 1; i < 10; i++) {count[i] += count[i - 1];}for (int i = n - 1; i >= 0; i--) {output[count[(arr[i] / exp) % 10] - 1] = arr[i];count[(arr[i] / exp) % 10]--;}for (int i = 0; i < n; i++) {arr[i] = output[i];}}
}

第四部分:排序算法的比较与选择

排序算法的选择往往取决于数据的特性、规模以及对时间与空间复杂度的不同需求。以下是一些常见排序算法的比较,包括它们的时间复杂度和空间复杂度。

1. 算法比较

冒泡排序
  • 时间复杂度:平均和最坏情况都是 O(n^2),最好情况是 O(n)(如果数据已经部分排序)。
  • 空间复杂度:O(1),因为它是原地排序算法。
选择排序
  • 时间复杂度:无论最好、最坏、平均情况都是 O(n^2)。
  • 空间复杂度:O(1),因为它是原地排序算法。
插入排序
  • 时间复杂度:平均和最坏情况都是 O(n^2),最好情况是 O(n)(如果数据已经排序)。
  • 空间复杂度:O(1),因为它是原地排序算法。
归并排序
  • 时间复杂度:最好、平均、最坏情况都是 O(n log n)。
  • 空间复杂度:O(n),需要额外的存储空间来临时存储数据。
快速排序
  • 时间复杂度:平均情况是 O(n log n),最坏情况是 O(n^2),但在实践中通常表现良好。
  • 空间复杂度:O(log n),这是递归调用的栈空间。
堆排序
  • 时间复杂度:最好、平均、最坏情况都是 O(n log n)。
  • 空间复杂度:O(1),可以调整为原地排序。
希尔排序
  • 时间复杂度:取决于增量序列,平均是 O(n log n),但最坏情况是 O(n^2)。
  • 空间复杂度:O(1),可以调整为原地排序。
计数排序
  • 时间复杂度:O(n + k),其中 k 是数据范围。
  • 空间复杂度:O(k),需要额外空间来存储计数数组。
桶排序
  • 时间复杂度:平均 O(n + k),其中 k 是桶的数量。
  • 空间复杂度:O(n + k),需要额外空间来存储桶。
基数排序
  • 时间复杂度:O(d * (n + k)),其中 d 是数字的位数,k 是基数。
  • 空间复杂度:O(n + k),需要额外空间来存储计数和临时数组。

2. 算法选择指南

  • 数据规模:对于小规模数据,简单排序算法(如插入排序)可能更高效。对于大规模数据,应考虑使用 O(n log n) 级别的算法,如快速排序或归并排序。
  • 数据特性:如果数据已经部分排序,插入排序或冒泡排序可能更有效。如果数据分布范围较小,计数排序或桶排序可能更合适。
  • 空间限制:如果内存空间受限,应优先选择原地排序算法,如堆排序或希尔排序。
  • 稳定性需求:如果需要保持相等元素的相对顺序,应选择稳定的排序算法,如归并排序或计数排序。
  • 实现复杂性:某些算法(如基数排序)虽然在特定情况下效率很高,但实现起来较为复杂。

选择合适的排序算法需要综合考虑上述因素,以实现最优的排序效果。

望读者能够将这些知识应用到实际工作中,提高编程能力和解决问题的能力。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com