数据结构与算法之快速排序

快速排序是一种基于分治思想的排序算法,其核心思想是通过选定一个元素(通常是数组中第一个或最后一个元素)作为基准值,将数组划分为左右两个子数组,使得左子数组中的元素都小于等于基准值,右子数组中的元素都大于等于基准值,然后对左右子数组分别递归地进行快速排序,直到子数组长度为1或0。

具体的算法流程如下:

1.选定基准值pivot,一般选取数组的第一个或最后一个元素作为基准值;

2.将数组分为两部分,左侧为小于等于基准值的元素,右侧为大于等于基准值的元素;

3.递归地对左右两部分进行快速排序,直至数组长度为1或0。

快速排序的时间复杂度为O(nlogn),且实际应用中效率较高。在排序的同时,快速排序也具有原地排序的特点,即不需要额外的辅助空间。
在这里插入图片描述



一、C语言之数据结构与算法之快速排序源码实现及详解

快速排序是一种常用的排序算法,它的核心思想是分治法,将序列分成两个子序列,其中一个序列的值都比另一个序列小,然后对这两个子序列进行递归操作,直到每个子序列只有一个元素为止。

快速排序的实现方法如下:

  1. 选取一个基准元素(一般选取第一个元素)。
  2. 将序列中所有比基准元素小的元素放在基准元素的左边,比基准元素大的元素放在右边。
  3. 对基准元素的左右两个子序列递归执行步骤1和步骤2。

下面是C语言实现快速排序的代码:

#include<stdio.h>

void quick_sort(int[],int,int);

int main(){
    int a[50],n,i;
    printf("Enter the number of elements:");
    scanf("%d",&n);
    printf("Enter array elements:");
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    quick_sort(a,0,n-1);
    printf("Array after sorting:");
    for(i=0;i<n;i++)
        printf("%d ",a[i]);
    return 0;
}

void quick_sort(int a[],int l,int u){
    int j;
    if(l<u){
        j=partition(a,l,u);
        quick_sort(a,l,j-1);
        quick_sort(a,j+1,u);
    }
}

int partition(int a[],int l,int u){
    int pivot,i,j,temp;
    pivot=a[l];
    i=l;
    j=u+1;
    do{
        do
            i++;
        while(a[i]<pivot && i<=u);
        do
            j--;
        while(a[j]>pivot);
        if(i<j){
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
    }while(i<j);
    a[l]=a[j];
    a[j]=pivot;
    return(j);
}

快速排序的时间复杂度为O(nlogn)。它的最坏情况下的时间复杂度为O(n^2),发生在序列已经排好序的情况下。快速排序是一种不稳定的排序算法,即相同元素不保证相对顺序不变。

在这里插入图片描述



二、C++语言之数据结构与算法之快速排序源码实现及详解

快速排序是一种常见的排序算法,它的时间复杂度为O(nlogn),是一种高效的排序方式之一。下面是C++语言实现快速排序的源码及详解:

#include<iostream>
using namespace std;

void Qsort(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--; // 从右边找第一个小于基准值的数
        if(i < j) a[i++] = a[j];
        while(i < j && a[i] <= pivot) i++; // 从左边找第一个大于基准值的数
        if(i < j) a[j--] = a[i];
    }
    a[i] = pivot; // 基准值归位
    Qsort(a, left, i-1); // 递归排序左边和右边的数
    Qsort(a, i+1, right);
}

int main(){
    int a[] = {3, 5, 1, 7, 4, 9, 6, 8, 2};
    int len = sizeof(a)/sizeof(int);
    Qsort(a, 0, len-1);
    for(int i = 0; i < len; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

首先我们需要定义一个递归函数Qsort,表示对数组进行快速排序。函数有三个参数,分别是待排序的数组a、数组左端点left和右端点right。函数的返回值是void,不需要返回任何值。

接下来我们需要判断排序是否结束。如果左端点left大于等于右端点right,则数组排序结束。此时我们直接返回,不需要再进行排序。

然后我们需要选择一个基准值pivot,我们选择左端点a[left]作为基准值。然后我们从右端点开始寻找第一个小于基准值的数a[j],找到后将它与a[i]交换。然后从左端点开始寻找第一个大于基准值的数a[i],找到后将它与a[j]交换。重复这个过程,直到i>=j为止。

此时我们将基准值a[left]与a[i]交换,基准值归位,这样就完成了一次快速排序。

最后我们需要对左半部分和右半部分进行递归排序,递归调用函数Qsort:Qsort(a, left, i-1)和Qsort(a, i+1, right)。

需要注意的是,在Qsort函数中,我们选择a[left]作为基准值,这需要满足left小于等于right,否则会导致数组的越界。所以在主函数中,我们需要计算数组的长度len,并将它减1,作为Qsort函数的右端点right的值。主函数的代码如下:

int main(){
    int a[] = {3, 5, 1, 7, 4, 9, 6, 8, 2};
    int len = sizeof(a)/sizeof(int);
    Qsort(a, 0, len-1);
    for(int i = 0; i < len; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

最后,我们再来看一下算法的时间复杂度。快速排序的平均时间复杂度为O(nlogn),最坏情况下的时间复杂度为O(n2)。在本例中,我们选择左端点作为基准值,如果数列本身就是有序的,那么每次基准值都是最小的数,这种情况下会使算法的时间复杂度为O(n2)。但是,在实际应用中,我们可以随机选择基准值来避免这种情况的出现,从而保证算法的时间复杂度为O(nlogn)。

在这里插入图片描述



三、java语言之数据结构与算法之快速排序源码实现及详解

快速排序是一种高效的排序算法,它的实现思路是基于分治法和递归的。快速排序的基本思想是:选取一个元素作为基准值,将数组分为两个子数组,一个子数组中的元素都小于基准值,另一个子数组中的元素都大于基准值。然后对这两个子数组分别进行快速排序,最终将整个数组排序。

下面是Java语言的快速排序的源码实现及详解:

public class QuickSort {
    /**
     * 快速排序的实现方法
     * @param arr 待排序的数组
     * @param low 数组的起始位置
     * @param high 数组的终止位置
     */
    public static void quickSort(int[] arr, int low, int high) {
        if (low < high) {
            int pivotIndex = partition(arr, low, high); // 计算基准值的位置
            quickSort(arr, low, pivotIndex - 1); // 对基准值左边的子数组进行快速排序
            quickSort(arr, pivotIndex + 1, high); // 对基准值右边的子数组进行快速排序
        }
    }

    /**
     * 计算基准值的位置
     * @param arr 待排序的数组
     * @param low 数组的起始位置
     * @param high 数组的终止位置
     * @return 基准值的位置
     */
    private static int partition(int[] arr, int low, int high) {
        int pivot = arr[low]; // 选取第一个元素作为基准值
        int left = low; // 左边子数组的起始位置
        int right = high; // 右边子数组的终止位置

        while (left < right) {
            // 从右边开始,寻找第一个小于基准值的元素的位置
            while (left < right && arr[right] >= pivot) {
                right--;
            }
            // 将小于基准值的元素交换到左边
            arr[left] = arr[right];

            // 从左边开始,寻找第一个大于基准值的元素的位置
            while (left < right && arr[left] <= pivot) {
                left++;
            }
            // 将大于基准值的元素交换到右边
            arr[right] = arr[left];
        }
        // 将基准值交换到它的最终位置
        arr[left] = pivot;
        // 返回基准值的位置
        return left;
    }
}

快速排序的实现过程可以分为两个步骤:

  1. 计算基准值的位置:我们选取数组中的第一个元素作为基准值,然后将整个数组分成两个子数组,一个子数组中的元素都小于基准值,另一个子数组中的元素都大于基准值。计算基准值的位置就是为了把数组分成这两个子数组。

  2. 对子数组进行快速排序:计算出基准值的位置后,我们将左边子数组和右边子数组分别进行递归调用快速排序算法,直到整个数组有序。

快速排序的时间复杂度为O(nlogn),其中n为数组的长度。快速排序是一种原地排序算法,不需要额外的存储空间。因此,快速排序是一种高效的排序算法,被广泛应用于现代计算机系统中。

在这里插入图片描述






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值