算法(经典快速排序及改进)

来源于屈婉玲的《算法设计与分析》第二版

经典快速排序算法:

伪码表示:

交换过程如图所示:

 C语言代码实现:

#include <iostream>
#include <stdio.h>
using namespace std;

int partitions(int a[],int p,int r)
{
    int x,i,j,temp;
    x=a[p];
    i=p;
    j=r;
    while(1)
    {
        while(a[j]>x)
            j--;
        while(a[i]<=x)
            i++;
        if(i<j)
        {
            temp=a[i];
            a[i]=a[j];
            a[j]=temp;
        }
        else
            return j;
    }

}
int quicksort(int a[],int p,int r)
{
    if(p<r)
    {
        int temp,q;
        temp=a[p];
        q=partitions(a,p,r);

        a[p]=a[q];
        a[q]=temp;
        quicksort(a,p,q-1);
        quicksort(a,q+1,r);
    }
    else
        return 0;
}
int main()
{
    int arr[10]{6,7,8,9,10,5,3,2,4,1};
    printf("排序前:");
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);
    printf("\n");
    quicksort(arr,0,9);
    printf("排序后:");
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);
    return 0;
}

改进算法参考于期刊:

罗可.一种提升快速排序效率的改进算法[J].无线互联科技,2022,19(10):119-121.

改进思想:除 Pivot 之外,每个数组值在快速排序法分割过程中都会被处理一次,并且处理程序可能只是将数组值与 Pivot 比较,也可能需要对换 Pivot 和数组值,这是一个最耗时但又不可避免的程序。所以,如果在这个过程中,用来同时找到数组的最小和最大值的话,那么每一次(Pass)完成排序定位的数组的值,从最初的 1(即Pivot)增加到 3(Pivot),即 Pivot、最小值和最大值,从而提高了算法的效率。

伪码描述:

 

交换过程如图所示:

 

C语言实现:

#include <iostream>
#include <stdio.h>
using namespace std;
int imported_partition(int data[],int left,int right);
int improved_quicksort(int data[],int left,int right)
{
    if(left<right)
    {
        int partion_index;
        partion_index = imported_partition(data,left,right);
        improved_quicksort(data,left+1,partion_index-1);
        improved_quicksort(data,partion_index+1,right-1);
    }
}
int imported_partition(int data[],int left,int right)
{
    int i=left+1;
    int j=right;
    int pivot=data[left];
    int max_index=left;
    int min_index=left;
    int temp;
    while(true){
        while(i<right && data[i]<=pivot)
        {
            if (data[i]<data[min_index])
                min_index=i;
            i+=1;
        }
            if(data[i]>data[max_index])
                max_index=i;
        while(j>left && data[j]>pivot)
        {
            if(data[j]>data[max_index])
                max_index=j;
            j-=1;
        }
            if(data[j]<data[min_index])
                min_index=j;
        if(j>i)
            {
                temp=data[i];
                data[i]=data[j];
                data[j]=temp;
                if(i==max_index)
                    max_index=j;
                if(j==min_index)
                    min_index=i;
            }
        else
                break;
    }
    if(j==min_index)
        min_index=left;
    if(left==max_index)
        max_index=j;
    data[left]=data[j];
    data[j]=pivot;
    temp=data[left];
    data[left]=data[min_index];
    data[min_index]=temp;
    temp=data[right];
    data[right]=data[max_index];
    data[max_index]=temp;
    return j;
}
int main()
{
    int arr[10]{6,7,8,9,10,5,3,2,4,1};
    printf("排序前:");
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);
    printf("\n");
    improved_quicksort(arr,0,9);
    printf("排序后:");
    for(int i=0;i<10;i++)
        printf("%d ",arr[i]);

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值