数据结构与C

数据结构与C 知识量:8 - 24 - 99

8.2 其他排序方法><

希尔排序- 8.2.1 -

希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959 年提出而得名。

希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

以下是使用C语言实现希尔排序的示例代码:

#include <stdio.h>  
  
void shellSort(int arr[], int n) {  
    int gap, i, j, temp;  
    for (gap = n / 2; gap > 0; gap /= 2) {  
        for (i = gap; i < n; i++) {  
            temp = arr[i];  
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {  
                arr[j] = arr[j - gap];  
            }  
            arr[j] = temp;  
        }  
    }  
}  
  
int main() {  
    int arr[] = {12, 34, 54, 2, 3};  
    int n = sizeof(arr) / sizeof(arr[0]);  
    shellSort(arr, n);  
    printf("Sorted array: ");  
    for (int i = 0; i < n; i++) {  
        printf("%d ", arr[i]);  
    }  
    return 0;  
}

这个代码中,shellSort函数接受一个整数数组和数组的大小作为参数,并使用希尔排序算法对数组进行排序。在主函数中,声明一个整数数组并调用shellSort函数对其进行排序。最后,使用循环遍历已排序的数组并打印其元素。

快速排序- 8.2.2 -

快速排序(Quick Sort)是一种常用的排序算法,它采用分治的思想,通过递归地划分数组并对其进行排序,最终得到有序的数组。

快速排序的基本步骤如下:

  1. 选择一个基准元素,通常选择数组的第一个元素。

  2. 重新排列数组,将比基准元素小的元素放在它的左边,将比基准元素大的元素放在它的右边。在这个过程结束时,基准元素就处于数组的最终位置。

  3. 递归地(recursive)把小于基准值元素的子数组和大于基准值元素的子数组排序。

以下是使用C语言实现快速排序的示例代码:

#include <stdio.h>  
  
void swap(int* a, int* b) {  
    int temp = *a;  
    *a = *b;  
    *b = temp;  
}  
  
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);  
    }  
}  
  
int main() {  
    int arr[] = {10, 7, 8, 9, 1, 5};  
    int n = sizeof(arr) / sizeof(arr[0]);  
    quickSort(arr, 0, n - 1);  
    printf("Sorted array: ");  
    for (int i = 0; i < n; i++) {  
        printf("%d ", arr[i]);  
    }  
    return 0;  
}

这个代码中,quickSort函数是递归地调用自身来对子数组进行排序。partition函数用于将数组划分为两部分,并返回基准元素的最终位置。在主函数中,声明一个整数数组并调用quickSort函数对其进行排序。最后,使用循环遍历已排序的数组并打印其元素。

堆排序- 8.2.3 -

堆排序(Heap Sort)是一种利用堆这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组来模拟堆的树形结构,以降低程序的复杂度。

堆排序可以分为两个主要部分:建堆和堆调整。建堆主要是构建一个最大堆或最小堆,将根节点设置为数组的最后一个元素;堆调整则是将堆顶元素与末尾元素交换,然后调整剩余元素使其继续保持最大堆或最小堆的性质。

以下是使用C语言实现堆排序的示例代码:

#include <stdio.h>  
  
void swap(int* a, int* b) {  
    int temp = *a;  
    *a = *b;  
    *b = temp;  
}  
  
void heapify(int arr[], int n, int i) {  
    int largest = i; // Initialize largest as root  
    int left = 2 * i + 1; // left = 2*i + 1  
    int right = 2 * i + 2; // right = 2*i + 2  
  
    // If left child is larger than root  
    if (left < n && arr[left] > arr[largest]) {  
        largest = left;  
    }  
  
    // If right child is larger than largest so far  
    if (right < n && arr[right] > arr[largest]) {  
        largest = right;  
    }  
  
    // If largest is not root  
    if (largest != i) {  
        swap(&arr[i], &arr[largest]);  
  
        // Recursively heapify the affected sub-tree  
        heapify(arr, n, largest);  
    }  
}  
  
void heapSort(int arr[], int n) {  
    // Build heap (rearrange array)  
    for (int i = n / 2 - 1; i >= 0; i--) {  
        heapify(arr, n, i);  
    }  
  
    // One by one extract an element from heap  
    for (int i = n - 1; i >= 0; i--) {  
        // Move current root to end  
        swap(&arr[0], &arr[i]);  
  
        // call max heapify on the reduced heap  
        heapify(arr, i, 0);  
    }  
}

归并排序- 8.2.4 -

归并排序(Merge Sort)是一种分治算法,它将一个大的问题分解为两个或更多个小的子问题,然后将这些子问题的解合并以得到原问题的解。

归并排序的基本步骤如下:

  1. 将待排序的序列划分为若干个子序列,每个子序列为1个元素,然后将这些子序列两两合并,得到新的有序序列。

  2. 将相邻的2个子序列合并,得到长度为2的有序序列。

  3. 重复步骤2,直到所有元素排序完毕。

以下是使用C语言实现归并排序的示例代码:

#include <stdio.h>  
  
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; // Calculate mid point to divide array into two halves.  
   
        mergeSort(arr, l, m); // Sort first half.  
        mergeSort(arr, m + 1, r); // Sort second half.  
   
        merge(arr, l, m, r); // Merge the sorted halves.  
    }  
}