C语言数据结构 快速排序实例详解

C语言数据结构 快速排序实例详解

什么是快速排序?

快速排序(Quicksort)是一种采用分治法(Divide and Conquer)的排序算法,通过将一个大问题逐步分解为小问题来解决的一种工具。

快速排序是一个比较快的排序算法,在平均状况下,排序n个项目要 O(n log n) 次比较,最坏情况下需要O(n^2)次比较,但这种状况并不常见。

快速排序算法的基本思想

快速排序的核心思想在于分治法,具体步骤如下:

  1. 选择一个枢轴元素piv;
  2. 将序列中小于等于枢轴元素的元素放在左边;大于枢轴元素的元素放在右边;
  3. 递归地对左右两部分进行排序。

如下图所示,在这个示例中,选取的枢轴元素为数字3,小于等于3的数放在左边,大于3的数放在右边。

             [ 5  2  6  3  8  7  1  4 ]
                      /   \
                [ 2  1  3  4 ]  [ 5  6  8  7 ]
                   /     \         /     \
               [ 1  2 ] [ 4  3 ] [ 5  6 ] [ 8  7 ]
                   \     /
                  [ 1  2  3  4 ]

快速排序的代码实现

下面我们将通过C语言来实现快速排序。这里给出两个示例,一个基于递归,另一个基于栈。

基于递归的实现

代码如下:

#include <stdio.h>

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

void main() {
    int a[] = {26, 27, 23, 17, 25, 31, 29, 19};
    int i;
    quickSort(a, 0, 7);
    for (i = 0; i < 8; i++)
        printf("%d ", a[i]);
    printf("\n");
}

基于栈的实现

代码如下:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int left;
    int right;
} Range;

typedef struct {
    Range r[100];
    int size;
} Stack;

Stack stack;

void push(int left, int right) {
    stack.r[stack.size].left = left;
    stack.r[stack.size].right = right;
    stack.size++;
}

Range pop() {
    stack.size--;
    return stack.r[stack.size];
}

void quickSort(int *a, int left, int right) {
    if (left >= right)
        return;
    push(left, right);
    while (stack.size > 0) {
        Range range = pop();
        int i = range.left;
        int j = range.right;
        int pivot = a[i];
        while (i < j) {
            while (a[j] >= pivot && i < j)
                j--;
            a[i] = a[j];
            while (a[i] <= pivot && i < j)
                i++;
            a[j] = a[i];
        }
        a[i] = pivot;
        if (range.left < i - 1)
            push(range.left, i - 1);
        if (range.right > i + 1)
            push(i + 1, range.right);
    }
}

void main() {
    int a[] = {35, 33, 42, 10, 14, 19, 27, 44, 26, 31};
    int i;
    quickSort(a, 0, 9);
    for (i = 0; i < 10; i++)
        printf("%d ", a[i]);
    printf("\n");
}

快速排序算法的复杂度分析

快速排序算法的时间复杂度可以分析如下:

  • 最坏情况下,每次划分只能将区间缩小1,需要n次划分,时间复杂度为O(n^2);
  • 最好情况下,每次划分所得的两个子区间长度一样,需要进行log n次划分,时间复杂度为O(n log n);
  • 平均情况下,快速排序的时间复杂度为O(n log n)。

空间复杂度方面,由于采用递归或栈来实现,每次递归或产生栈帧的空间的大小为log n,所以空间复杂度为 O(log n)。

小结

快速排序算法是经典的排序算法之一,其核心思想在于分治法,适用于排序大规模数据的场景。本文通过C语言的实现代码,详细讲解了快速排序算法的基本思想、基于递归和基于栈两种实现方式,以及时间复杂度和空间复杂度等方面的分析。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构 快速排序实例详解 - Python技术站

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

相关文章

  • c语言数据结构之并查集 总结

    C语言数据结构之并查集总结 简介 并查集,也称作不相交集合,是一种树型的数据结构。并查集用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。 并查集只有两个操作: find:确定某个元素属于哪个子集。它可以被用来确定两个元素是否属于同一子集。 union:将两个子集合并成同一个集合。 基本实现 以快速查找find和…

    数据结构 2023年5月17日
    00
  • JavaScript中数据结构与算法(四):串(BF)

    JavaScript中数据结构与算法(四):串(BF) 一、串的定义 在计算机科学中,串(string)是由零个或多个字符组成的有限序列。零个字符的串称为空串(empty string),也叫做空格串(null string)。串中的字符数称为串的长度(length)。 二、串BF算法的定义 串的BF算法,也称为朴素算法(Brute-Force Algori…

    数据结构 2023年5月17日
    00
  • Java数据结构常见几大排序梳理

    Java数据结构常见几大排序梳理 在Java中,数据排序是非常常见的操作。下面我们详细讲解一下Java数据结构常见几大排序的梳理。 常见几大排序 Java数据结构中常见几种排序算法包括: 冒泡排序(Bubble Sort) 快速排序(Quick Sort) 插入排序(Insertion Sort) 选择排序(Selection Sort) 希尔排序(Shel…

    数据结构 2023年5月17日
    00
  • Java数据结构与算法之栈(动力节点Java学院整理)

    Java数据结构与算法之栈攻略 什么是栈? 栈是一种线性结构,属于“先进后出”(Last In First Out,LIFO)的数据结构。它只允许在栈顶进行插入和删除操作。 栈的实现 栈的实现有两种方式: 基于数组实现的顺序栈(ArrayStack) 基于链表实现的链式栈(LinkedStack) 1. 基于数组实现的顺序栈 顺序栈的实现需要一个固定大小的数…

    数据结构 2023年5月17日
    00
  • Redis五种数据结构在JAVA中如何封装使用

    Redis 是一款高性能的键值存储数据库,支持五种不同的数据结构:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。在Java中使用Redis需要封装对应的数据结构,本文将详细介绍如何封装Redis的五种数据结构。 封装Redis字符串数据结构 Redis字符串数据结构对应Java中的String类…

    数据结构 2023年5月17日
    00
  • JavaScript数据结构与算法之链表

    JavaScript数据结构与算法之链表 什么是链表 链表是一种线性数据结构,它由一个一个的节点组成,每个节点包含两个部分:当前节点存储的数据,以及指向下一个节点的指针。相比于数组,链表可以实现更加灵活的内存分配,可以动态增加或删除节点,但访问链表中的节点比访问数组要慢。 单向链表 单向链表是最简单的一种链表,它每个节点只有一个指针,指向它的下一个节点。单向…

    数据结构 2023年5月17日
    00
  • MySQL底层数据结构选用B+树的原因

    MySQL底层数据结构选用B+树的原因主要是因为B+树具有以下优点: 能够快速查找B+树的查找速度非常快,时间复杂度为O(log n),在海量数据的环境中,能够快速定位目标数据。因为B+树每次查找只需要遍历树高度的次数,即使数据量很大,树的高度也很小。 能够高效地进行增删改操作B+树的平衡性能够保证树的高度非常小,大部分操作只需要遍历树的高度,而不是整颗树,…

    数据结构 2023年5月17日
    00
  • 二叉搜索树的本质

    引言 打算写写树形数据结构:二叉查找树、红黑树、跳表和 B 树。这些数据结构都是为了解决同一个基本问题:如何快速地对一个大集合执行增删改查。 本篇是第一篇,讲讲搜索树的基础:二叉搜索树。 基本问题 如何在一千万个手机号中快速找到 13012345432 这个号(以及相关联信息,如号主姓名)? 最笨的方案 把一千万个手机号从头到尾遍历一遍,直到找到该手机号,返…

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