算法分析与设计 实验一:分治算法和贪婪法

实验一  分治算法和贪婪法

                                      

一、实验目的

  1. 掌握分治算法的设计思想与分析方法;
  2. 能够按题目要求编程实现分治算法;
  3. 理解和掌握贪婪算法的基本思想;
  4. 使用贪婪算法求解背包问题以及最小花费生成树问题。

二、实验仪器及设备

  1. 硬件环境:PC机一台
  2. 软件环境:Windows 11、C语言(Visual C++ 6.0)

三、实验内容

  1. 采用分治算法求10个实数{ 9,3,6,2,1,8,4,5,7,23 }序列中的最大元素和最小元素,并分析算法的时间复杂度。
  2. 采用分治算法方法实现快速排序算法。要求:输入数组为{9,4,6,2,5,8,4,5,6,22 };限定数组排序范围;输出显示为递增顺序排序的数组。
  3. 利用贪婪法求如下背包问题的最优解:n=5,M=100,价值P={20,30,66,40,60},重量为w={10,20,30,40,50}。
    1、分治法求最大最小值
    #include <stdio.h>
    #include <stdlib.h>
    void maxmin(int a[], int *e_max, int *e_min, int low, int high) 
    {
        if (high - low <= 1) 
    	{
            *e_max = (a[low] > a[high]) ? a[low] : a[high];
            *e_min = (a[low] < a[high]) ? a[low] : a[high];
        } 
    	else 
    	{
            int mid = (low + high)/2;
            int x1, x2, y1, y2;
            maxmin(a, &x1, &y1, low, mid);
            maxmin(a, &x2, &y2, mid + 1, high);
            *e_max = (x1 > x2) ? x1 : x2;
            *e_min = (y1 < y2) ? y1 : y2;
        }
    }
    int main() 
    {
        int a[10] = {9, 3, 6, 2, 1, 8, 4, 5, 7, 23};
        int e_max, e_min, low, high;
        printf("输入范围: (low and high) ");
        scanf("%d %d", &low, &high);
        if (low < 0 || low >= 10 || high < 0 || high >= 10 || low >= high)
    	{
            printf("超出范围\n");
            return 1;  // 返回非零值表示程序异常退出
        }
        maxmin(a, &e_max, &e_min, low, high);
        printf("Max: %d\n", e_max);
        printf("Min: %d\n", e_min);
        return 0;
    }
    
    
    
    
    
    
    
    2、分治法实现快速排序
    #include <stdio.h>
    void swap(int* a, int* b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    int split(int A[], int low, int high)
    {
        int x = A[low]; // 将第一个元素作为枢轴
        int i = low;
        for (int j = low + 1; j <= high; j++)
        {
            if (A[j] <= x)
            {
                i++;    
                if (i != j) {  swap(&A[i], &A[j]); // 交换元素 }  
    }
        }
        swap(&A[low], &A[i]); // 交换枢轴和A[i]
        return i; // 返回枢轴的位置
    }
    void quick_sort(int A[], int low, int high)
    {
        if (low < high)
        {
            int k = split(A, low, high);
            quick_sort(A, low, k - 1); // 对左侧子数组进行排序
            quick_sort(A, k + 1, high); // 对右侧子数组进行排序
        }
    }
    int main()
    {
        int arr[] = {9, 4, 6, 2, 5, 8, 4, 5, 6, 22};
        int n = sizeof(arr) / sizeof(arr[0]);
        printf("原始数组:");
        for (int i = 0; i < n; i++)
        {
            printf("%d ", arr[i]);
        }
        printf("\n");
        quick_sort(arr, 0, n - 1);
        printf("排序后的数组:");
        for (int j = 0; j < n; j++) // 将循环中的变量重命名为 j
        {
            printf("%d ", arr[j]);
        }
        printf("\n");
        return 0;
    }
    
    
    
    
    3、贪婪法求解可分割背包问题最优解
    #include <stdio.h>
    typedef struct
    {
        float p;
        float w;
        float v; //价值
    }object;
    void knapsackGreedy(float M, object insurance[], int n)
    {
        int i;
        float m = M;
        float totalValue = 0.0;
        for (i = 0; i < n; i++)
    	{
            insurance[i].v = insurance[i].p / insurance[i].w;
        }
        for (i = 0; i < n - 1; i++) // 按照单位价值降序排列物品
    	{  
            for (int j = i + 1; j < n; j++)
    		{
                if (insurance[j].v > insurance[i].v)
    			{
                    object temp = insurance[j];
                    insurance[j] = insurance[i];
                    insurance[i] = temp;
                }
            }
        }
        printf("选择的物品及其放入比例:\n");
        for (i = 0; i < n; i++)
    	{
            if (m >= insurance[i].w) 
    		{
                printf("物品%d: 1.00\n", i + 1);
                m -= insurance[i].w;
                totalValue += insurance[i].p;
            }
    		else
    		{
                float ratio = m / insurance[i].w;
                printf("物品%d: %.2f\n", i + 1, ratio);
                totalValue += ratio * insurance[i].p;
                m = 0;
                break;
            }
        }
        printf("总价值:%.2f\n", totalValue);
    }
    int main() 
    {
        int n = 5;
        float M = 100;
        object in[] = {{20, 10, 0}, {30, 20, 0}, {66, 30, 0}, {40, 40, 0}, {60, 50, 0}};
        knapsackGreedy(M, in, n);
        return 0;
    }
    

    运行截图如下:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值