常见的7种排序算法小结
一.常见的排序算法有以下几种:
-
冒泡排序:每次比较相邻两个元素,然后交换它们的位置,重复这个过程直到整个数组排序完成。
-
选择排序:每次从未排序的部分选出最小(或最大)的元素,然后与未排序部分的第一个元素交换位置,如此反复直到整个数组排序完成。
-
插入排序:从第二个元素开始,将每个元素插入到已排序的数组中的适当位置,直到整个数组排序完成。
-
快速排序:以数组中的某个元素为基准(比如中间元素),将数组分成两个子数组,左边的子数组的所有元素都小于基准元素,右边的子数组的所有元素都大于基准元素,然后递归地重复这个过程直到排序完成。
-
归并排序:将数组分成两个子数组,递归地排序每个子数组,然后将每个子数组合并成一个新数组,直到整个原数组排序完成。
-
堆排序:通过将数组转换为最大堆来排序,然后重复从堆中弹出最大元素并将其放入已排序的数组中的过程,直到整个数组排序完成。
-
希尔排序:使用不同的步长将数组分成几个子数组,针对每个子数组进行插入排序,然后逐渐减小步长,如此反复直到整个数组排序完成。
以上是常见的排序算法,不同的排序算法适用于不同的场景,选择合适的排序算法可以提高程序的效率。
1.冒泡排序java示例
以下是一个使用Java实现的冒泡排序示例:
public class BubbleSort {
public static void bubbleSort(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
swap(nums, j, j + 1);
}
}
}
}
public static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
bubbleSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,bubbleSort()方法实现了冒泡排序的主要逻辑。外层循环用于确定比较的轮数,内层循环用于每轮比较相邻的元素并交换位置。swap()方法用于交换两个元素的位置。最后在main()方法中调用bubbleSort()方法对数组排序并输出结果。
2.选择排序java示例
以下是一个使用Java实现的选择排序示例:
public class SelectionSort {
public static void selectionSort(int[] nums) {
int n = nums.length;
for (int i = 0; i < n - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < n; j++) {
if (nums[j] < nums[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
swap(nums, i, minIndex);
}
}
}
public static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
selectionSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,selectionSort()方法实现了选择排序的主要逻辑。外层循环用于确定每轮的最小元素,内层循环用于找到未排序部分中的最小元素并记录其索引。如果最小元素不在未排序部分的第一个位置,则将其与未排序部分的第一个元素交换位置。swap()方法用于交换两个元素的位置。最后在main()方法中调用selectionSort()方法对数组排序并输出结果。
3.插入排序java示例
以下是一个使用Java实现的插入排序示例:
public class InsertionSort {
public static void insertionSort(int[] nums) {
int n = nums.length;
for (int i = 1; i < n; i++) {
int temp = nums[i];
int j = i - 1;
while (j >= 0 && nums[j] > temp) {
nums[j + 1] = nums[j];
j--;
}
nums[j + 1] = temp;
}
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
insertionSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,insertionSort()方法实现了插入排序的主要逻辑。外层循环用于确定待排序部分的下一个元素,内层循环用于在已排序部分中逐个比较并将待排序元素插入到合适的位置。最后在main()方法中调用insertionSort()方法对数组排序并输出结果,这里使用了简单的for-each循环。
4.快速排序java示例
以下是一个使用Java实现的快速排序示例:
public class QuickSort {
public static void quickSort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
int pivot = nums[left];
int i = left, j = right;
while (i < j) {
while (i < j && nums[j] >= pivot) {
j--;
}
nums[i] = nums[j];
while (i < j && nums[i] <= pivot) {
i++;
}
nums[j] = nums[i];
}
nums[i] = pivot;
quickSort(nums, left, i - 1);
quickSort(nums, i + 1, right);
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
quickSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,quickSort()方法实现了快速排序的主要逻辑。首先选取基准元素(这里选取了左端元素),然后使用双指针i和j在分区中移动,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。当双指针相遇时,将基准元素放置到当前位置,然后对左边和右边的子数组分别使用递归进行快排。最后在main()方法中调用quickSort()方法对数组排序并输出结果。
5.归并排序java示例
以下是一个使用Java实现的归并排序示例:
public class MergeSort {
public static void mergeSort(int[] nums, int left, int right) {
if (left >= right) {
return;
}
int mid = (left + right) / 2;
mergeSort(nums, left, mid);
mergeSort(nums, mid + 1, right);
merge(nums, left, mid, right);
}
public static void merge(int[] nums, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (nums[i] < nums[j]) {
temp[k++] = nums[i++];
} else {
temp[k++] = nums[j++];
}
}
while (i <= mid) {
temp[k++] = nums[i++];
}
while (j <= right) {
temp[k++] = nums[j++];
}
for (i = 0; i < temp.length; i++) {
nums[left + i] = temp[i];
}
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
mergeSort(nums, 0, nums.length - 1);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,mergeSort()方法实现了归并排序的主要逻辑。首先将数组分成左右两部分,对左右两部分分别使用递归进行归并排序,然后将两个有序的子数组进行归并。merge()方法用于归并两个有序的子数组,使用临时数组存储归并后的结果。最后在main()方法中调用mergeSort()方法对数组排序并输出结果。
6.堆排序java示例
以下是一个使用Java实现的堆排序示例:
public class HeapSort {
public static void heapSort(int[] nums) {
// 构建最大堆
buildMaxHeap(nums);
// 从堆顶开始依次将最大值放置在数组末尾
for (int i = nums.length - 1; i >= 1; i--) {
swap(nums, 0, i);
maxHeapify(nums, 0, i);
}
}
public static void buildMaxHeap(int[] nums) {
int n = nums.length;
// 从末尾的父节点开始向上构建最大堆
for (int i = n / 2 - 1; i >= 0; i--) {
maxHeapify(nums, i, n);
}
}
public static void maxHeapify(int[] nums, int i, int size) {
int left = 2 * i + 1;
int right = 2 * i + 2;
int largest = i;
if (left < size && nums[left] > nums[largest]) {
largest = left;
}
if (right < size && nums[right] > nums[largest]) {
largest = right;
}
if (largest != i) {
swap(nums, i, largest);
maxHeapify(nums, largest, size);
}
}
public static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
heapSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,heapSort()方法实现了堆排序的主要逻辑。首先使用buildMaxHeap()方法构建最大堆,即将数组转换为符合堆的性质:每一个父结点的值大于其左右子结点的值。然后从堆顶开始依次将最大值放置在数组末尾,并使用maxHeapify()方法对堆进行调整,使之重新满足堆性质。swap()方法用于交换两个元素的位置。最后在main()方法中调用heapSort()方法对数组排序并输出结果。
7.希尔排序java示例
以下是一个使用Java实现的希尔排序示例:
public class ShellSort {
public static void shellSort(int[] nums) {
int n = nums.length;
// 计算增量序列
int gap = 1;
while (gap < n / 3) {
gap = gap * 3 + 1;
}
while (gap > 0) {
// 对每个子数组使用插入排序
for (int i = gap; i < n; i++) {
int temp = nums[i];
int j = i;
while (j >= gap && nums[j - gap] > temp) {
nums[j] = nums[j - gap];
j -= gap;
}
nums[j] = temp;
}
gap = gap / 3;
}
}
public static void main(String[] args) {
int[] nums = {4, 2, 8, 1, 3, 6, 5, 7};
shellSort(nums);
for (int num : nums) {
System.out.print(num + " ");
}
}
}
在上面的代码中,shellSort()方法实现了希尔排序的主要逻辑。首先计算增量序列,然后依次对每个子数组使用插入排序,其中插入排序的增量为gap。在每一轮中,将每个子数组的前gap个元素看做整体,插入排序可以使得这个子数组“几乎有序”。不断地缩小gap的值,并在缩小后的子数组中使用插入排序,最终整个数组能够完全有序。最后在main()方法中调用shellSort()方法对数组排序并输出结果。
二.以下是一些算法刷题的经验:
-
列表分类:将题目分为一系列规律相似、解法类似的题目,对于一种题型,可以选择一道经典题目作为代表,学会解法后再尝试其他题目。
-
固定套路:对于一些常见的问题,经常会有固定的解法,例如动态规划、二分查找、回溯算法等。多注意这些算法的分类,以便在做题时能够快速想到对应的算法。
-
反复练习:多练习同一类型的题目,对某些重点知识点反复进行练习,可以使自己更熟练掌握这些算法。
-
掌握数据结构:算法解法与数据结构密切相关。因此,对于各种常见数据结构,如栈、队列、链表、二叉树等,需要掌握其基本操作和应用场景,这有助于掌握数据结构上的算法。
-
代码实现:多实现一些算法,提高自己的程序设计能力。实际的编码会帮助你理解算法的细节和实现方法。
-
充分利用优秀的资源:网络上有很多优秀的编程博客、视频课程、开源项目等资源,可以帮助你更好地掌握算法。在学习过程中,多参考这些资源,可以更快更好地掌握算法知识。
转载自:https://juejin.cn/post/7229126088226734136