算法设计与分析头歌实验五:分治法

1关:求一组数据中最大的两个数

#include <stdio.h>



void max_min(int a[],int m,int n,int *min1,int *min2,int *max1,int *max2);



void main()

{

    int num,i;

    scanf("%d",&num);

    int a[num];

    for(i=0;i<num;i++)

        scanf("%d",&a[i]);



    /**********  Begin  **********/

    int min1,min2;

    int max1,max2;

    max_min(a,0,num-1,&min1,&min2,&max1,&max2);



    printf("max1=%d max2=%d\n",max1,max2);

    printf("min1=%d min2=%d",min1,min2);

    /**********  End  **********/

}

void max_min(int a[],int m,int n,int *min1,int *min2,int *max1,int *max2)

{

int lmin1,lmin2,lmax1,lmax2;

int rmin1,rmin2,rmax1,rmax2;

int mid;

 

if(m==n)//分治子数组中只有一个数

{

*min1=*min2=*max1=*max2=a[m];

}

 

else//分治子数组中不止一个数

    if(m==n-1)//分治子数组中仅有2个数

    {

        if(a[m]<a[n])

        {

            *min1=a[m];

            *min2=a[n];

            *max1=a[n];

            *max2=a[m];

        }

        else

        {

            *min1=a[n];

            *min2=a[m];

            *max1=a[m];

            *max2=a[n];

        }

    }

 

    else//分治子数组中有超过2个数

    {

        mid=(m+n)/2;

        max_min(a,m,mid,&lmin1,&lmin2,&lmax1,&lmax2);

        max_min(a,mid+1,n,&rmin1,&rmin2,&rmax1,&rmax2);

 

        //**************************************************

        //确定出数组中最小的两个数

        //**************************************************

        if(lmin1<rmin1)//左子数组最小数<右子数组最小数

        {

            if(lmin2<rmin1)

            {

            *min1=lmin1;

            *min2=lmin2;

            }

            else

            {

            *min1=lmin1;

            *min2=rmin1;

            }

        }

        else//右子数组最小数<左子数组最小数

            if(rmin2<lmin1)

            {

            *min1=rmin1;

            *min2=rmin2;

            }

            else

            {

            *min1=rmin1;

            *min2=lmin1;

            }

 

        //**************************************************

        //确定出数组中最大的两个数

        //**************************************************

        if(lmax1>rmax1)//左子数组最大数>右子数组最大数

        {

            if(lmax2>rmax1)

            {

            *max1=lmax1;

            *max2=lmax2;

            }

            else

            {

            *max1=lmax1;

            *max2=rmax1;

            }

        }

        else//右子数组最大数>左子数组最大数

            if(rmax2>lmax1)

            {

            *max1=rmax1;

            *max2=rmax2;

            }

            else

            {

            *max1=rmax1;

            *max2=lmax1;

            }

        }

}

第2关:求一组数据的和

#include "stdio.h"



/**********  Begin  **********/



#include<stdlib.h> 

int add(int *a,int left,int right);



int main()

{



    int i,num;

    scanf("%d", &num);

    int array[num];

    for (i = 0; i < num; i++)

    {

        scanf("%d", &array[i]);

    }

    int sum=add(array,0,num-1);

     printf("分治法求出数组元素的和为:%d",sum);



    return 0;

 }



 int add(int a[],int left,int right)

 {

    int mid;

    if(left==right)

    {

        return a[left];

     }

     else if (left == right-1)

     {

        return a[left]+a[right];

     }

     else

     {

        mid=(left+right)/2;

        return add(a,left,mid)+add(a,mid+1,right);

     }

 }

/**********  End  **********/


3关:找出数组中第 k 个小的元素

#include <stdio.h>



/**********  Begin  **********/



int Solve(int a[], int s, int t,int k)

{

    //划分算法

    int i = s, j = t;

    int temp = a[s];

    if (s < t)

    {

        while (i != j)

        {

            while (j > i&&a[j] >= temp)

                j--;

            a[i] = a[j];

            while (i < j&&a[i] <= temp)

                i++;

            a[j] = a[i];

        }

        a[i] = temp;



        //求解

        if (k - 1 == i)

            return a[i];

        else if (k - 1 < i)

        {

            return Solve(a, s, i - 1, k);

        }

        else return Solve(a, i + 1, t, k);

    }

    else if (s == t && s == k - 1)

        return a[k - 1];

}



int main()

{

   

    int n,i,k;

    scanf("%d%d",&n,&k);

    int a[n];



    for (i = 0; i <= n; i++)

        scanf("%d",&a[i]);



    printf("第%d小的元素是%d",k,Solve(a,0,n,k));

   

    return 0;

}



/**********  End  **********/

参照原文:

https://blog.csdn.net/xiongwanfeng/article/details/79097906

https://blog.csdn.net/cintrycintry/article/details/103032941

https://blog.csdn.net/qq_43759081/article/details/121888090

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值