必须知道的C语言八大排序算法(收藏)

必须知道的C语言八大排序算法(收藏)

简介

排序算法(sorting algorithms)是计算机程序设计中处理数据的重要技术之一,常见于数据处理程序中。其功能是按照指定的方式将所输入的数据进行排序。排序算法分为内部排序和外部排序,本文主要讲解C语言中的八大内部排序算法。

八大排序算法

  1. 冒泡排序
  2. 选择排序
  3. 插入排序
  4. 希尔排序
  5. 归并排序
  6. 快速排序
  7. 堆排序
  8. 计数排序

冒泡排序

冒泡排序是一种简单的排序算法,它重复的遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就交换位置。其时间复杂度为O(n^2)。

示例代码:

void bubbleSort(int arr[], int n) {
    int i, j;
    for (i = 0; i < n-1; i++)
        for (j = 0; j < n-i-1; j++)
            if (arr[j] > arr[j+1]) {
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
}

选择排序

选择排序是一种简单直观的排序算法,它的工作原理是:首先找到序列中最小的元素,其次将它放在序列的起始位置;接着,再从剩余未排序的元素中寻找最小的值,将其放在已排序序列的末尾。以此类推,直到所有元素均排列完毕。其时间复杂度为O(n^2)。

示例代码:

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;
        int temp = arr[i];
        arr[i] = arr[min_idx];
        arr[min_idx] = temp;
    }
}

(接下来五种算法类似的方式展开介绍)

插入排序

插入排序是一种简单直观的排序算法,它的工作原理是在已排序序列中从后向前扫描,找到相应位置并插入。其时间复杂度为O(n^2)。

示例代码:

void insertionSort(int arr[], int n) {
    int i, key, j;
    for (i = 1; i < n; i++) {
        key = arr[i];
        j = i - 1;
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j = j - 1;
        }
        arr[j + 1] = key;
    }
}

希尔排序

希尔排序是一种改进型的插入排序,其基本思路是将待排序的序列划分成若干个子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插入排序。其时间复杂度为O(n*log2n)。

示例代码:

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;
        }
    }
}

归并排序

归并排序是一种分治思想的排序算法,它的基本思想是将待排序序列分成若干个子序列,每个子序列都是有序的,然后再将有序子序列合并成一个有序序列。其时间复杂度为O(n*log2n)。

示例代码:

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);
    }
}

快速排序

快速排序是一种由C.A.R.Hoare在1960年提出的一种分治思想的原地快速排序算法。其基本思路是使用基准元素将一个序列分为左右两部分,一边存贮比该基准元素小的元素,另一边存储比该基准元素大的元素,而后递归处理这两个序列,直到这个序列不可分为止。其时间复杂度最差情况下为O(n^2),但平均情况下为O(n*log2n)。

示例代码:

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

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(n*log2n)。

示例代码:

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) {
        swap(&arr[i], &arr[largest]);
        heapify(arr, n, largest);
    }
}

void heapSort(int arr[], int n) {
    for (int i = n / 2 - 1; i >= 0; i--)
        heapify(arr, n, i);
    for (int i=n-1; i>=0; i--) {
        swap(&arr[0], &arr[i]);
        heapify(arr, i, 0);
    }
}

计数排序

计数排序是一种线性排序算法,其基本思路是统计待排序元素中小于等于每个元素的个数(称为元素k),最终确定该元素的位置。算法需确定待排序元素的最大和最小值。其时间复杂度为O(n+k),k为元素范围。

示例代码:

void countSort(int arr[], int n) {
    int output[n];
    int max = arr[0];
    for (int i = 1; i < n; i++) {
        if (arr[i] > max)
            max = arr[i];
    }
    int count[max + 1];

    for (int i = 0; i <= max; ++i)
        count[i] = 0;

    for (int i = 0; i < n; i++)
        count[arr[i]]++;

    for (int i = 1; i <= max; i++)
        count[i] += count[i - 1];

    for (int i = n - 1; i >= 0; i--) {
        output[count[arr[i]] - 1] = arr[i];
        count[arr[i]]--;
    }

    for (int i = 0; i < n; i++)
        arr[i] = output[i];
}

总结

在实际应用中,我们需要考虑算法的时间复杂度、空间复杂度和稳定性这三个因素。每一种排序都有其独特的应用场景和相应的优缺点。选择合适的排序算法对于提升程序运行效率是相当必要的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:必须知道的C语言八大排序算法(收藏) - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • PHP 冒泡排序 二分查找 顺序查找 二维数组排序算法函数的详解

    PHP是一门广泛应用于Web开发领域的脚本语言,而算法在计算机科学领域也是非常重要的一部分,掌握一些常用的算法能够为程序员的工作带来极大的便利。本文将详细讲解PHP冒泡排序、二分查找、顺序查找、二维数组排序算法函数的详解。 冒泡排序 冒泡排序是一种比较简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就将它们交换,直到没有任何一对…

    算法与数据结构 2023年5月19日
    00
  • C/C++浅析邻接表拓扑排序算法的实现

    C/C++浅析邻接表拓扑排序算法的实现 什么是拓扑排序 在图论中,若存在一种拓扑序列,使得对于任意的有向边(u,v),u在序列中都在v的前面,则称该图为拓扑排序,该序列称为拓扑序列。拓扑排序是一个有向无环图(DAG, Directed Acyclic Graph)的一种线性序列。 拓扑排序算法的实现 拓扑排序算法的实现一般基于邻接表,其核心思路为:先将所有入…

    算法与数据结构 2023年5月19日
    00
  • JS实现数组按升序及降序排列的方法

    JS实现数组按升序和降序排列的方法有很多种,下面我将从简单到复杂分享几种方法。 sort()方法 sort()方法是JS的一个数组方法,可以对数组排序。它有一个可选的排序函数,用于规定排序规则。 升序排列: let arr = [3, 1, 4, 7, 2]; arr.sort((a, b) => a – b); console.log(arr); /…

    算法与数据结构 2023年5月19日
    00
  • JS中的算法与数据结构之字典(Dictionary)实例详解

    下面我将详细讲解“JS中的算法与数据结构之字典(Dictionary)实例详解”的完整攻略。 什么是字典? 字典是一种存储唯一键和对应值的数据结构,每个键对应一个值。JavaScript 中的对象就是字典的一种实现,通过键值对来存储和访问数据。 字典的操作 字典支持以下几种操作: 添加键值对 删除键值对 查找键值对 获取所有键 获取所有值 字典的实现 下面是…

    算法与数据结构 2023年5月19日
    00
  • 基于Go语言实现冒泡排序算法

    基于Go语言实现冒泡排序算法 什么是冒泡排序 冒泡排序(Bubble Sort)是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历数列的工作是重复地进行,因而得名“冒泡排序”。该算法因其简单的实现方式和易于理解的原理而广泛应用。 冒泡排序算法实现方式 冒泡排序的算法原理如下: 比较相邻的元素。如果第一个…

    算法与数据结构 2023年5月19日
    00
  • stl常用算法(Algorithms)介绍(stl排序算法、非变序型队列)

    STL常用算法介绍 STL(Standard Template Library)是C++标准库的一个庞大组成部分,提供了大量的常用算法,容器以及迭代器等等。这些工具都可以被拿来用来解决大部分的计算问题。其中stl常用算法主要包括排序算法和非变序型队列,下面进行详细讲解。 stl排序算法 STL提供了丰富的排序算法模板,可以直接拿来使用,无需重新实现。以下是一…

    算法与数据结构 2023年5月19日
    00
  • C语言快速排序函数用法(qsort)

    C语言快速排序函数用法(qsort) 简介 快速排序是一种常见的排序算法,而C语言中的qsort函数则是一种快速排序的实现。使用qsort函数,我们无需自己编写快速排序算法的代码,只需要提供一个排序所需的比较函数即可。使用qsort函数,既可以方便的排序数组,还可以排序链表等数据结构。 函数原型 void qsort(void *base, size_t n…

    算法与数据结构 2023年5月19日
    00
  • 一道JS前端闭包面试题解析

    下面我来为你讲解一道 JS 前端闭包面试题的完整攻略。 面试题 下面是面试题的题目与内容: for (var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 0); } 要求输出 0, 1, 2, 3, 4,但是实际上却是输出了 5, 5, 5, 5, 5。请问这是为什么?…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部