说了这么久的数据结构,理论性比较强,下面我们来进入算法部分,运用之前学的数据结构来实现算法。今天的主体部分是排序,难度不大。
排序的算法是比较简单实用的算法,也是很多的算法的基础。也分很多种,可以根据时间空间难度不同的,有序数据能够被更高效地查找、分析和处理
。
选择算法是一个时间复杂度O(n2),空间复杂度是O(1),运行时间比较长。其主要思想是每次从未排序的部分中选择最小(或最大)的元素,将其放在已排序部分的末尾。以下是选择排序的详细步骤:
初始状态:
arr
,长度为 n
。外层循环:
arr[0]
到 arr[n-2]
,依次执行以下步骤。寻找最小值:
i
到 n-1
),找到最小元素的索引 min_index
。arr[i]
开始,比较 arr[i]
、arr[i+1]
、…、arr[n-1]
的值,记录下最小值的索引。交换元素:
arr[i]
)交换。重复步骤 2 到 4:
n-2
)。完成排序:
public class SelectionSort {
// 方法:选择排序
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;
}
}
// 如果找到的最小元素不是当前元素,则交换
if (minIndex != i) {
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
}
//测试选择排序
public static void main(String[] args) {
int[] arr = {64, 25, 12, 22, 11};
System.out.println("排序前的数组:");
printArray(arr);
selectionSort(arr);
System.out.println("排序后的数组:");
printArray(arr);
}
//打印数组
public static void printArray(int[] arr) {
for (int j : arr) {
System.out.print(j + " ");
}
System.out.println();
}
}
冒泡排序(Bubble Sort)是一种简单的排序算法,它的基本思想是通过多次遍历列表,不断地将相邻的元素进行比较并交换,使得每一轮遍历之后,最大的元素会“冒泡”到数组的末尾。这个过程会重复进行,直到整个数组排序完成。下面是对冒泡排序的详细解释:
初始状态:
n
。外层循环:
n-1
轮,因为在最坏的情况下,所有元素都需要比较 n-1
次才能确定其最终位置。内层循环:
逐步缩小范围:
结束条件:
n-1
轮比较,但一旦发现某一轮没有发生交换,就可以提前终止排序。最坏情况:O(n2) —— 当数组是逆序时,算法需要执行最多次数的比较和交换。
最好情况:O(n) —— 当数组已经排序时,算法只需一次遍历即可结束。
平均情况:O(n^2) —— 大多数情况下,需要执行比较次数与最坏情况相似。
插入排序(Insertion Sort)是一种简单且直观的排序算法,特别适合于小规模数据的排序。它的基本思想是将待排序的元素逐个插入到已经排好序的部分,直到整个序列有序。插入排序的工作方式类似于我们打牌时将新牌插入到已排序的牌中。
取第一个为基准值:
逐步插入:
插入元素:
下面是使用 Java 实现的插入排序的完整代码示例:
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]; // 将大于 key 的元素向后移动
j--;
}
arr[j + 1] = key; // 插入当前元素到找到的位置
}
}
// 主方法:测试插入排序
public static void main(String[] args) {
int[] arr = {5, 2, 9, 1, 5, 6};
System.out.println("排序前的数组:");
printArray(arr);
insertionSort(arr);
System.out.println("排序后的数组:");
printArray(arr);
}
// 辅助方法:打印数组
public static void printArray(int[] arr) {
for (int j : arr) {
System.out.print(j + " ");
}
System.out.println();
}
}
insertionSort
方法:
arr
,并对其进行排序。1
开始遍历到数组的最后一个元素,key
变量存储当前待插入的元素。key
应该插入的位置。数组元素移动:
key
时,将该元素向后移动一位,以便为 key
腾出插入的位置。插入元素:
j + 1
就是 key
应该插入的位置。printArray
方法:
时间复杂度:
O(n^2)
(当数组逆序时)。O(n)
(当数组已经排序时)。O(n^2)
。空间复杂度:O(1)
,因为它是原地排序算法。
稳定性:插入排序是稳定的排序算法,即相等元素的相对顺序不会改变。
插入排序在小规模数据集上表现良好,并且在数据部分有序时效率较高。
快速排序(Quicksort)是一种高效的排序算法,最早由英国计算机科学家托尼·霍尔提出。它采用了分治策略
,将一个数组分成两个子数组,并递归地对这两个子数组进行排序。快速排序在平均情况下具有非常好的性能,其时间复杂度为 (O(n log n))。分治算法就是将问题进行切片
,牺牲空间换取时间。
快速排序通过以下步骤来对数组进行排序:
选择基准(Pivot):
分区(Partitioning):
递归排序:
下面是使用 Java 实现快速排序的代码示例:
public class QuickSort {
// 方法:快速排序
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// 获取分区点(pivot)
int pi = partition(arr, low, high);
// 递归排序左半部分
quickSort(arr, low, pi - 1);
// 递归排序右半部分
quickSort(arr, pi + 1, high);
}
}
// 分区方法:返回分区点
private static int partition(int[] arr, int low, int high) {
int pivot = arr[high]; // 选择最右边的元素作为基准
int i = (low - 1); // i 指向小于 pivot 的最后一个元素
for (int j = low; j < high; j++) {
// 如果当前元素小于或等于 pivot
if (arr[j] <= pivot) {
i++;
// 交换 arr[i] 和 arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// 将 pivot 放置到正确的位置
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
// 主方法:测试快速排序
public static void main(String[] args) {
int[] arr = {10, 7, 8, 9, 1, 5};
System.out.println("排序前的数组:");
printArray(arr);
quickSort(arr, 0, arr.length - 1);
System.out.println("排序后的数组:");
printArray(arr);
}
// 辅助方法:打印数组
public static void printArray(int[] arr) {
for (int j : arr) {
System.out.print(j + " ");
}
System.out.println();
}
}
quickSort
方法:
low
和 high
分别代表当前排序范围的起始和结束索引。partition
方法:
递归:
quickSort
方法中,排序完成后,基准元素将数组分为两个部分,算法会继续递归地对这两个部分进行快速排序。快速排序由于其高效的时间复杂度和较低的空间复杂度,通常被认为是最佳的通用排序算法之一,广泛应用于实际中。
大概一般的排序就这些,学一下思想就好了,大多数时候学Java里面的我用的大多数时候都是sort解决。
持续更新中~~