本文将从以下几个方面详细阐述使用C语言将一个数组从大到小排序的方法。
一、选择排序
选择排序是一种最简单直观的排序算法,它的基本思想是找到未排序部分中的最小值(或最大值),然后将其放到已排序序列的末尾。下面是选择排序的代码实现:
void selectionSort(int arr[], int n) { int i, j, min_idx; for (i = 0; i < n-1; i++) { min_idx = i; for (j = i+1; j < n; j++) { if (arr[j] < arr[min_idx]) { min_idx = j; } } swap(&arr[min_idx], &arr[i]); } }
在选择排序中,我们在内循环中查找最小值,并将其与当前循环的第一个元素进行交换。该算法的时间复杂度为O(n^2)。
二、插入排序
插入排序是另一种简单的排序算法,它的基本思想是将未排序部分的第一个元素插入到已排序部分的正确位置。下面是插入排序的代码实现:
void insertionSort(int arr[], int n) { int i, j, key; for (i = 1; i < n; i++) { key = arr[i]; j = i-1; while (j >= 0 && arr[j] < key) { arr[j+1] = arr[j]; j--; } arr[j+1] = key; } }
在插入排序中,我们将未排序部分的第一个元素插入到已排序部分的正确位置。插入排序的时间复杂度为O(n^2)。
三、快速排序
快速排序是一种常见且性能优异的排序算法,它的基本思想是通过选择一个基准元素,将数组分为两部分,使得左边部分的元素都小于等于基准元素,右边部分的元素都大于等于基准元素。然后递归地对左右两个部分进行排序。下面是快速排序的代码实现:
int partition(int arr[], int low, int high) { int pivot = arr[high]; int i = (low - 1); for (int j = low; j <= high- 1; j++) { if (arr[j] >= pivot) { i++; swap(&arr[i], &arr[j]); } } swap(&arr[i + 1], &arr[high]); return (i + 1); } void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } }
在快速排序中,我们首先选择一个基准元素,将数组分为两部分。对于左边部分的元素和右边部分的元素,我们递归地使用快速排序进行排序。快速排序的时间复杂度为O(nlogn)。
四、归并排序
归并排序是另一种性能优异的排序算法,它的基本思想是将数组分为两半,对每一半递归地使用归并排序。然后将两个已经排序的子数组合并成一个有序数组。下面是归并排序的代码实现:
void merge(int arr[], int l, int m, int r) { int i, j, k; int n1 = m - l + 1; int n2 = r - m; int L[n1], R[n2]; for (i = 0; i < n1; i++) { L[i] = arr[l + i]; } for (j = 0; j < n2; j++) { R[j] = arr[m + 1+ j]; } i = 0; j = 0; 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 mergeSort(int arr[], int l, int r) { if (l < r) { int m = l+(r-l)/2; mergeSort(arr, l, m); mergeSort(arr, m+1, r); merge(arr, l, m, r); } }
在归并排序中,我们先将数组分为两半,然后递归地使用归并排序对每一半进行排序。最后,我们将两个有序子数组合并成一个有序数组。归并排序的时间复杂度为O(nlogn)。