仲舟のMOOC第十三周编程作业

这周不难,好好反思一下是不是在等答案,有自己想过吗?
第一题上学期水平

///*题目:实现简单选择排序算法
///*作者:仲舟                                       
///*难度:★
///*完成时间:2021.07.02
#include <stdio.h>
#include<malloc.h>
#define Max 50000     /*N为数据量大小*/

void SelectSort(int R[],int N); //简单选择排序,对R中R[1]...R[N]进行升序排序,每一趟排序后输出中间状态。
void Print(int R[],int N);

int  main() {
    int *R,N,i;                     /*数据存储在R[1]...R[N]中*/
    scanf("%d",&N);
    R=(int *)malloc((N+1)*sizeof(int));
    for(i=1; i<=N; i++)
        scanf("%d",&R[i]);
    Print(R,N);
    SelectSort(R,N);
    Print(R,N);
    return 0;
}

void Print(int R[],int N) {
    int i;
    for (i=1; i<N; i++)
        printf("%d,",R[i]);
    printf("%d\n",R[N]);
}

SelectSort(int R[],int N) {
    for(int i=1; i<N; i++) {
        /*1.找到最小值*/
        int min=R[i],minpos=i,temp;//设未排序第一个为最小值,最小下标,临时变量
        for(int j=i+1; j<N+1; j++)//i后面全找一遍
            if(R[j]<min) {//如果比min小,那就是最小
                min=R[j];//记录值
                minpos=j;//记录下标
            }
        /*2.交换*/
        temp=R[minpos];
        R[minpos]=R[i];
        R[i]=temp;
        /*3.打印*/
        Print(R,N);
    }
}

第二题题目不难但很难理解,我拍个图解释什么叫归并排序
在这里插入图片描述

///*题目:二路归并排序算法递归实现
///*作者:仲舟                                       
///*难度:★★★★
///*完成时间:2021.07.02
#include <stdio.h>
#include<malloc.h>
#define Max 50000     /*N为数据量大小*/

void MergeSort(int R[],int N,int low,int high); //二路归并排序,R中具有N个元素,该函数实现对R中R[low]...R[high]进行升序排序
void Merge(int R[],int N,int u,int m,int v);//将有序段R[u..m],R[m+1..v]归并到R[u..v]
void Print(int R[],int N);

int  main()
{
  int *R,N,i;                     /*数据存储在R[1]...R[N]中*/
  scanf("%d",&N);
  R=(int *)malloc((N+1)*sizeof(int));
  for(i=1;i<=N;i++)
    scanf("%d",&R[i]);
  MergeSort(R,N,1,N);
  Print(R,N);
  return 0;
}

void Print(int R[],int N)
{
    int i;
    for (i=1;i<N;i++)
        printf("%d,",R[i]);
    printf("%d\n",R[N]);
}

void MergeSort(int R[],int N,int low,int high)
{
    int mid;
    if (low<high)
    {
        mid=(low+high)/2;
        MergeSort(R,N,low,mid);
        MergeSort(R,N,mid+1,high);//注:以上两部分是先把整个数组的左右两边拆分成零碎的数字
        Merge(R,N,low,mid,high);
    }
}
//你的代码写在这里

void Merge(int R[],int N,int u,int m,int v)
{
    int S[N],i=u,j=m+1,k=0;//开辟一个空间存有序数列、i(j)为第一(二)个子序列正处理下标,k为S数组下标
    while(i<=m&&j<=v)//i在R[u,m],j在R[m+1,v],k在S[0,N-1],为防止越界,当有一个子序列满了,停止比较
    {
        if(R[i]<=R[j])//把小的存在S中
            S[k++]=R[i++];
        else
            S[k++]=R[j++];
    }
    while(i<=m)//如果第一个子序列没排满,剩下的全排
        S[k++]=R[i++];
    while(j<=v)//同上
        S[k++]=R[j++];
    for(int m=0,n=u;n<=v;m++,n++)//S[0,N-1]就是R[u,v]顺序数了,再把S全部赋值给R
        R[n]=S[m];
}

第三题考快速排序,不懂的可以去下面链接看:https://blog.csdn.net/fhb1922702569/article/details/91868338

///*题目:快速排序算法递归实现
///*作者:仲舟                                       
///*难度:★★★★
///*完成时间:2021.07.02
#include <stdio.h>
#include<malloc.h>
#define Max 50000     /*N为数据量大小*/

int Partition(int R[],int low,int high); //对R[low]..R[high]进行一趟划分
void QuickSort(int R[],int N,int low,int high ); //对R[low]..R[high]进行快速排序,其中N是原始待排序数组的大小,便于输出整个数组的中间状态
void Print(int R[],int N);

int  main() {
    int *R,N,i;                     /*数据存储在R[1]...R[N]中*/
    scanf("%d",&N);
    R=(int *)malloc((N+1)*sizeof(int));
    for(i=1; i<=N; i++)
        scanf("%d",&R[i]);
    QuickSort(R,N,1,N);
    Print(R,N);
    return 0;
}

void Print(int R[],int N) {
    int i;
    for (i=1; i<N; i++)
        printf("%d,",R[i]);
    printf("%d\n",R[N]);
}

void QuickSort(int R[],int N,int low,int high ) {
    int p;
    if (low<high) {
        p=Partition(R,low,high);  //对数组R从low到high进行一次划分
        Print(R,N); //输出当前整个数组的状态
        QuickSort(R,N,low,p-1); //对数组R前半段(low,p-1) 进行快速排序
        QuickSort(R,N,p+1,high);//对数组R后半段(p+1,high)进行快速排序
    }
}
//你的代码写在这里

int Partition(int R[],int low,int high) {
    int i = low,j = high,key = R[low];//i,j拷贝,key为比较键
    if (low >= high) //如果low >= high说明排序结束了
        return ;
    while (low < high) //该while循环结束一次表示交换了一轮
    {
        while (low < high && key <= R[high])//从后往前找第一个小于key(第一个数)的值(low<high为在有效区域的寻找必要条件)
            --high; //向前寻找
        if (key > R[high])
            R[low++] = R[high]; //直接赋值, 不用交换
        while (low < high && key >= R[low])//从前往后找第一个大于key(第一个数)的值
            ++low; //向后寻找
        if (key < R[low])
            R[high--] = R[low]; //直接赋值, 不用交换
    }
    R[low] = key; //查找完一轮后key值归位, 不用比较一次就互换一次。此时key值将序列分成左右两部分
    return low;
}

仲舟原创,未经允许禁止转载!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值