我的算法笔记(5)分治(1)

排序

这里先介绍俩种排序方法----归并排序和快速排序

1.归并排序

引例 归并排序的图片描述

图片来源:菜鸟教程
菜鸟教程的归并排序演示

引例 对十个数的归并排序

// merge sort
#include<stdio.h>




int a[10]={5,3,13,25,84,64,70,20,90,100};
int b[10];//一个临时数组
int min(int x,int y)
{//先写一个min函数用来比较数字的大小
    return x<y?x:y;
}
void Merge(int a[],int s,int m,int e,int b[])
{   int i=0;
    int x=0;//负责指向b
    int x1=s,x2=m+1;//分别负责指向需要归并的俩个数组
    while (x1<=m && x2<=e){
        if (a[x1] < a[x2])//开始比较待归并的俩格数组,比较元素的大小,小的就放在前面
            b[x++]=a[x1++];
        else
            b[x++]=a[x2++];
    }
    //只要有一个数组的数全部都排完了,那么我就可以吧另一个数组剩下的全部数就都放在临时数组里了
    while (x1 <=m)
        b[x++] = a[x1++];
    while (x2<=e)
        b[x++] = a[x2++];
    for (i=0;i<e-s+1;i++)  //这里e-s+1是因为e是从len-1开始的,所以+1
        a[s+i] = b[i];//把b中已经排好的数组重新赋值给a
}
void MergeSort(int a[],int s,int e,int b[])//一个参数是要排序的数组,另一个是数组的开始,结尾,b临时存放
{
    if(s<e){
        int m = s + (e-s)/2; //找到中间的位置
        MergeSort(a,s,m,b);//对前一半排序

        MergeSort(a,m+1,e,b);//对后一半排序

        Merge(a,s,m,e,b);//进行并的操作
    }
}

//写一个演义的函数
void Display(int a[],int s,int e){
    int i;
    for (i=s;i<e+1;i++)
        printf("%d,",a[i]);
    printf("\n");
    return ;

}


int main()
{   int i;
    int len = sizeof(a)/sizeof(int);//得到a的长度
    Display(a,0,len-1);
    MergeSort(a,0,len-1,b);//进行排序操作
    Display(a,0,len-1);
}

结果如图所示:
程序结果演示
从代码中我们可以看出,我们使用了递归的思想完成了归并排序的操作,其中比较重要的俩格步骤,就是“分(Mergesort)”和“和(Merge)”俩个函数
在Mergesort函数中:

void MergeSort(int a[],int s,int e,int b[])//一个参数是要排序的数组,另一个是数组的开始,结尾,b临时存放
{
    if(s<e){
        int m = s + (e-s)/2; //找到中间的位置
        MergeSort(a,s,m,b);

        MergeSort(a,m+1,e,b);//对后一半排序

        Merge(a,s,m,e,b);//进行并的操作
    }
}

主要是进行了分半的操作,通过二分的过程,把一个大的数组变成一个个小的局部的数组,然后再通过Merge函数,分别对每一小片的数组再次整理组合在了一起.

void Merge(int a[],int s,int m,int e,int b[])
{   int i=0;
    int x=0;//负责指向b
    int x1=s,x2=m+1;//分别负责指向需要归并的俩个数组
    while (x1<=m && x2<=e){
        if (a[x1] < a[x2])//开始比较待归并的俩格数组,比较元素的大小,小的就放在前面
            b[x++]=a[x1++];
        else
            b[x++]=a[x2++];
    }
    //只要有一个数组的数全部都排完了,那么我就可以吧另一个数组剩下的全部数就都放在临时数组里了
    while (x1 <=m)
        b[x++] = a[x1++];
    while (x2<=e)
        b[x++] = a[x2++];
    for (i=0;i<e-s+1;i++)  //这里e-s+1是因为e是从len-1开始的,所以+1
        a[s+i] = b[i];//把b中已经排好的数组重新赋值给a
}

快速排序

图片描述

快速排序的图片
此处图片出处:五分钟学算法

引例:对十个数字进行排序

//QuickSort

#include<stdio.h>
#define BUF_SIZE 10

void display(int array[],int maxlen)
{
    int i;
    for (i=0;i<maxlen;i++)
    {
        printf("%d,",array[i]);

    }
    printf("\n");
}
void swap(int *a,int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}
// the implementation of quicksort

void quicksort(int array[],int begin,int end)
{
    int i,j;
    int k = array[begin];
    if (begin >= end )
        return;
        i = begin;  // 把array[begin]作为基准数,因此array[begin+1]开始与基准数吧比较
        j = end;
    while (i!=j)
    {   while (j>i && array[j] >=k) // 保证k右边的数都比K 大
        --j;    //这个循环的意思就是说,如果满足这个条件,那么我的指针就向下一个元素指去;
        swap(&array[i],&array[j]);//自然,不满足循环的条件的话,就会互换位置。
        while (j >i && array[i]<=k) //保证k左边的数,都比K 小
        ++i;
        swap(&array[i],&array[j]);

    }//此时就已经处理完成了数组,
    //进行k左右俩边数组的分别排序
    quicksort(array,begin,i-1);
    quicksort(array,i+1,end);
}

main()
{
    int n;
    int array[BUF_SIZE] = {12,85,25,16,34,23,49,95,17,61};
    int maxlen = BUF_SIZE;
    printf("排序前的数组:\n");
    display(array,maxlen);

    quicksort(array,0,maxlen-1); // 快速排序
    printf("排序后的数组:\n");
    display(array,maxlen);
}

结果如图所示:
在这里插入图片描述
在给出的快排代码中,我是让a[0]先作为k,然后开始比较。
代码解读:

void quicksort(int array[],int begin,int end)
{
    int i,j;
    int k = array[begin];
    if (begin >= end )
        return;
        i = begin;  // 把array[begin]作为基准数,因此array[begin+1]开始与基准数吧比较
        j = end;
    while (i!=j)
    {   while (j>i && array[j] >=k) // 保证k右边的数都比K 大
        --j;    //这个循环的意思就是说,如果满足这个条件,那么我的指针就向下一个元素指去;
        swap(&array[i],&array[j]);//自然,不满足循环的条件的话,就会互换位置。
        while (j >i && array[i]<=k) //保证k左边的数,都比K 小
        ++i;
        swap(&array[i],&array[j]);

    }//此时就已经处理完成了数组,
    //进行k左右俩边数组的分别排序
    quicksort(array,begin,i-1);
    quicksort(array,i+1,end);
}

在快排实现的代码中,我们可以看到,我设置了俩个变量i,j然后通过与k的比较,不断地进行交换位置还有指针向中间的移动,到最后使得i,j指向中间的位置,然后,再次递归调用quicksort函数,分别对中间左右的数组元素再次进行排序。
上一篇:我的算法笔记(4)二分查找1
下一篇:我的算法笔记(6)动态规划1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Pat晴神宝典是一本关于算法笔记。它由知名的算法专家Pat编写,是一本系统全面的算法学习资料。这本宝典包含了许多不同类型的算法,涉及了各个领域的问题解决方法。 Pat晴神宝典首先介绍了算法的基础知识,如时间复杂度、空间复杂度、数据结构等。然后它深入探讨了各种经典的算法,如排序算法、搜索算法、图算法等。每个算法都有详细的说明和代码实现,以及算法的优缺点和应用场景。宝典还提供了大量的练习题和习题解答,帮助读者巩固所学的算法知识。 Pat晴神宝典不仅仅是一个算法的技术手册,它还讲述了算法的设计思想和解题方法。宝典中有许多实际问题的案例分析,解释了如何使用不同的算法解决实际问题。它还提供了一些常见算法的优化方法和改进思路,帮助读者更好地掌握算法的运用。 总结来说,Pat晴神宝典是一本涵盖了广泛的算法知识的笔记。无论是初学者还是有经验的程序员,都可以从中获得宝贵的算法学习和应用经验。它不仅帮助读者提高解决问题的能力,还培养了读者的算法思维和创造力。无论在学术研究还是工程开发中,这本宝典都是一本不可或缺的参考书。 ### 回答2: PAT晴神宝典是一本算法学习笔记。PAT(Programming Ability Test)是中国程序设计竞赛的一种形式,它旨在提高学生的程序设计能力和算法思维能力。晴神指的是晴天老师,他是一位在算法竞赛界非常有影响力的老师,他编写了《算法笔记》一书。 这本《算法笔记》包含了程序设计竞赛中常用的数据结构和算法的讲解和实践。它主要分为四个部分:基础部分、数据结构、算法以及习题。基础部分主要介绍了程序设计的基本开发环境以及常用的算法思想和技巧,如递归、分治和动态规划等。数据结构部分涵盖了常见的数据结构,如树、图和堆等,以及它们的实现和应用。算法部分介绍了各种算法的设计思想和实现方法,如贪心算法、搜索算法和图论算法等。习题部分提供了大量的练习题,并给出了详细的解题思路和代码。 《算法笔记》以简洁清晰的语言、丰富的例子和详细的讲解,帮助读者掌握算法的基本原理和应用技巧。它不仅适用于想要参加编程竞赛的学生和程序员,也适用于对算法感兴趣的人士。通过阅读该书,读者能够系统地学习和应用算法,提高编程能力和算法思维能力。 总之,PAT晴神宝典是一本覆盖广泛且深入浅出的算法学习笔记,对于学习和应用算法的人士来说,它是一本十分有价值的资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞲_大河弯弯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值