深入学习C语言中常见的八大排序

深入学习C语言中常见的八大排序

前言

排序算法是计算机科学中的基本问题之一,是计算机领域内经典且常见的算法问题之一。排序算法对于优化数据检索、数据压缩、数据库查询效率等方面都有着重要的意义。
本文将为您详细讲解常见的八种排序算法的原理、时间复杂度以及应用场景,希望能够对您学习和了解排序算法提供帮助。

简介

排序算法是将一串数据按照一定的规则进行排列,排序算法可以归为两类:内部排序和外部排序。所谓内部排序,就是数据记录在内存中进行排序。而外部排序是指在排序过程中需要使用外部存储器。
本文主要介绍常见的内部排序算法。

具体排序算法

冒泡排序(Bubble Sort)

冒泡排序是一种基本的排序算法,它重复地走访过要排序的数列,一遍又一遍地比较相邻的两个数。每一遍排序结束后,都会将其中经过比较后较大的数交换到该循环遍历到的末尾。时间复杂度:O(n^2)。

示例:

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

选择排序(Selection Sort)

选择排序是一种不稳定的简单排序算法。它的工作原理是先找到序列中最小的数,将其放在序列的最前端,再从剩余未排好序的序列中找到最小值,放在已排好序的数列的后面,依此类推,直到整个序列排序完毕。时间复杂度:O(n^2)。

示例:

void selection_sort(int a[], int n){
    for(int i=0;i<n-1;i++){
        int min_index=i;
        for(int j=i+1;j<n;j++){
            if(a[min_index]>a[j]){
                min_index=j;
            }
        }
        if(min_index!=i){
            int temp=a[i];
            a[i]=a[min_index];
            a[min_index]=temp;
        }
    }
}

插入排序(Insertion Sort)

插入排序是一种简单的排序算法,它的基本思想是将未排序的元素插入已排序的元素中。时间复杂度:O(n^2)。

示例:

void insertion_sort(int a[], int n){
    for(int i=1;i<n;i++){
        int temp=a[i];
        int j=i-1;
        while(j>=0 && a[j]>temp){
            a[j+1]=a[j];
            j--;
        }
        a[j+1]=temp;
    }
}

希尔排序(Shell Sort)

希尔排序是插入排序的一种高效改进算法。希尔排序采用了分组排序的方式,使数组元素在一定程度上有序,从而更快地达到最终排序结果。时间复杂度:O(nlogn)。

示例:

void shell_sort(int a[], int n){
    for(int step=n/2;step>=1;step/=2){
        for(int i=step;i<n;i++){
            int temp=a[i];
            int j=i-step;
            while(j>=0 && a[j]>temp){
                a[j+step]=a[j];
                j-=step;
            }
            a[j+step]=temp;
        }
    }
}

归并排序(Merge Sort)

归并排序是一种稳定的排序算法。它采用了分治策略,将输入序列递归地划分为较小的序列,然后对这些子序列进行合并,最终得到完整有序序列。时间复杂度:O(nlogn)。

示例:

void merge(int a[], int left, int mid, int right){
    int i=left, j=mid+1, k=0;
    int temp[right-left+1];
    while(i<=mid && j<=right){
        if(a[i]<=a[j]){
            temp[k++]=a[i++];
        }else{
            temp[k++]=a[j++];
        }
    }
    while(i<=mid){
        temp[k++]=a[i++];
    }
    while(j<=right){
        temp[k++]=a[j++];
    }
    for(int p=0;p<k;p++){
        a[left+p]=temp[p];
    }
}

void merge_sort(int a[], int left, int right){
    if(left>=right){
        return;
    }
    int mid=left+(right-left)/2;
    merge_sort(a, left, mid);
    merge_sort(a, mid+1, right);
    merge(a, left, mid, right);
}

快速排序(Quick Sort)

快速排序是一种分治排序算法,它采用了基准值的思想,通过递归地将数据分解为基准值的左右两个子集,然后将两个子集不断递归,直到排序完成。时间复杂度:O(nlogn)。

示例:

void quick_sort(int a[], int left, int right){
    if(left>=right){
        return;
    }
    int i=left, j=right, pivot=a[left];
    while(i<j){
        while(i<j && a[j]>pivot){
            j--;
        }
        while(i<j && a[i]<=pivot){
            i++;
        }
        if(i<j){
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }
    a[left]=a[i];
    a[i]=pivot;
    quick_sort(a, left, i-1);
    quick_sort(a, i+1, right);
}

堆排序(Heap Sort)

堆排序是一种基于树型结构的排序算法,它是对选择排序的一种改进。堆排序将序列看作一个完全二叉树,每个节点都比其左右子树的所有节点都大或都小,然后将该序列不断调整为一个小根堆或大根堆,最后直接输出堆顶元素即可进行排序。时间复杂度:O(nlogn)。

示例:

void adjust_heap(int a[], int i, int n){
    int child=2*i+1;
    int temp=a[i];
    while(child<n){
        if(child+1<n && a[child]<a[child+1]){
            child++;
        }
        if(a[i]<a[child]){
            a[i]=a[child];
            i=child;
            child=2*i+1;
        }else{
            break;
        }
        a[i]=temp;
    }
}

void heap_sort(int a[], int n){
    for(int i=n/2-1;i>=0;i--){
        adjust_heap(a, i, n);
    }
    for(int i=n-1;i>=0;i--){
        int temp=a[0];
        a[0]=a[i];
        a[i]=temp;
        adjust_heap(a, 0, i);
    }
}

计数排序(Counting Sort)

计数排序是一种稳定的排序算法,其核心思想是:枚举数组 A 中的每个元素 x,统计数组 A 中小于等于 x 的元素个数,并将元素 x 放置到数组 B 中对应下标的位置上。计数排序性能优秀,但是要求待排序数组中的元素必须是有确切范围的整数。时间复杂度:O(n+k)。

示例:

void counting_sort(int a[], int n){
    int max_num=a[0];
    for(int i=1;i<n;i++){
        if(a[i]>max_num){
            max_num=a[i];
        }
    }
    int counting[max_num+1];
    memset(counting,0,sizeof(counting));
    for(int i=0;i<n;i++){
        counting[a[i]]++;
    }
    for(int i=1;i<=max_num;i++){
        counting[i]+=counting[i-1];
    }
    int temp[n];
    for(int i=n-1;i>=0;i--){
        temp[--counting[a[i]]]=a[i];
    }
    for(int i=0;i<n;i++){
        a[i]=temp[i];
    }
}

结尾

本文详细讲解了常见的八种排序算法的原理、时间复杂度以及应用场景。通过学习本文,相信读者可以自己实现各种排序算法,提高算法的实现能力,也希望本文能够对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入学习C语言中常见的八大排序 - Python技术站

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

相关文章

  • Java针对ArrayList自定义排序的2种实现方法

    这里给出针对ArrayList自定义排序的两种方法的详细攻略,分别为使用Comparator接口和使用Comparable接口。 1.使用Comparator接口 Comparator接口是JAVA中的一个接口, 我们可以在其中实现自定义的一些比较规则, 然后使用这些规则去对一些数据进行排序。 接下来是这种方式的实现步骤: 第一步:定义比较规则 我们需要实现…

    算法与数据结构 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
  • php实现快速排序的三种方法分享

    那么现在我将为您介绍“php实现快速排序的三种方法分享”的完整攻略。 什么是快速排序 快速排序(Quick Sort)通常被认为是对冒泡排序的一种改进。在冒泡排序中,需要进行多次的数据比较和交换操作,而快速排序与其不同之处在于它通过一个基准值将待排序的数组分成两个部分。在计算机领域,快速排序是一种常见的排序算法。 快速排序的常规实现思路 快速排序的常规实现思…

    算法与数据结构 2023年5月19日
    00
  • C++STL函数和排序算法的快排以及归并排序详解

    C++ STL函数和排序算法的快排以及归并排序详解 1. 什么是STL? STL(Standard Template Library)是C++标准库中的一部分,它是由若干个模板类和函数构成的集合,提供了一些常用的数据结构和算法。 其中,数据结构包括vector(可变长数组)、list(双向链表)等,算法包括sort(排序)、find(查找)等。 2. STL…

    算法与数据结构 2023年5月19日
    00
  • C语言基本排序算法之插入排序与直接选择排序实现方法

    C语言基本排序算法之插入排序与直接选择排序实现方法 本文将介绍C语言中两种常见的基本排序算法:插入排序和直接选择排序。我们将会详细阐述它们的实现方法,并提供示例代码来帮助理解和实践。 插入排序 插入排序是一种简单而常见的排序算法,它将待排序的数列分成已排序和未排序两部分,初始时已排序部分只包含一个元素,随着算法的运行,每次从未排序部分中取出第一个元素插入到已…

    算法与数据结构 2023年5月19日
    00
  • java简单选择排序实例

    Java简单选择排序是一种基于比较的排序算法,其基本思想是每次从待排序数据中选取最小(或最大)的元素,放到已排序的数据的末尾,直到所有元素都被排序完成。以下是Java简单选择排序实现的完整攻略: 算法步骤 遍历待排序的数组,每次选择最小的元素。 将已排序区间的末尾与最小元素进行交换。 扫描完整个数组,排序完成。 代码示例 下面给出了Java的简单选择排序的代…

    算法与数据结构 2023年5月19日
    00
  • C#实现优先队列和堆排序

    C#实现优先队列和堆排序攻略 什么是优先队列? 优先队列(Priority Queue)是在数据结构中使用频率很高的一种类型,它的主要特点是能够在数据插入时将数据进行优先级的排序。 并且每次取出数据时取的是优先级最高的数据。 通常情况下我们使用最大堆来实现优先队列。 最大堆是一种特殊的堆,它的特点是每个结点都大于等于它的子结点。 什么是堆排序? 堆排序是一种…

    算法与数据结构 2023年5月19日
    00
  • 浅谈2路插入排序算法及其简单实现

    浅谈2路插入排序算法及其简单实现 概述 2路插入排序算法是插入排序算法的一种变体,其主要思想是将待排序数据集分成两个子序列,分别进行插入排序,最后将两个排好序的子序列合并成一个有序序列。2路插入排序算法比普通的插入排序算法在特定数据集下可以获得更好的排序效果。 实现思路 2路插入排序算法可以分为以下几个步骤: 将待排序数据集按照大小分成两个子序列,分别进行插…

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