分治与减治算法实验:题目2 排序中分治法的程序设计

这篇具有很好参考价值的文章主要介绍了分治与减治算法实验:题目2 排序中分治法的程序设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言:

一、实验内容

二、实验目的

三、实验步骤

四、实验过程

1、算法分析

2、写出伪代码

3、代码实现

4、代码详解

5、用例测试

6、复杂度分析

总结


前言:

分治法是一种将复杂问题分解为若干个相同或相似的子问题,然后递归地求解子问题,最后将子问题的解合并为原问题的解的算法设计思想。减治法是一种将复杂问题简化为规模较小的同类问题,然后递归地求解简化后的问题,最后得到原问题的解的算法设计思想。分治法和减治法都是利用递归技术实现的算法。

排序是计算机科学中最基本也最重要的问题之一,它的目的是将一组无序的数据按照某种规则排列成有序的数据。排序中有许多经典的分治法和减治法的应用,例如快速排序、归并排序、堆排序等。这些排序算法都有各自的优缺点,需要根据不同的场景和需求选择合适的算法。

本实验旨在通过排序中分治法的程序设计,掌握分治法和减治法在排序问题上的应用,了解不同排序算法的原理、步骤、性能和特点,能够使用高级语言实现和测试这些排序算法,并能够分析和比较它们之间的异同。

本文中使用的语言是C语言,使用的ide是devc++
 

一、实验内容

给出一个初始序列,分别用归并法和快速排序两种分治法将所给序列变为有序序列,输出结果,输出是要有文字说明。请任选一种语言编写程序实现上述算法,并分析其算法复杂度

二、实验目的

(1)掌握归并排序和快速排序的划分方法;

(2)掌握归并排序和快速排序的具体分治策略;

(3)在掌握的基础上编程两种排序方法的实现过程。

三、实验步骤

1、写出伪代码进行算法描述

2、使用c++编写程序完成上述算法

3、使用测试用例对算法进行测试

4、对算法的复杂度进行分析

四、实验过程

1、算法分析

归并排序和快速排序都是分治算法的经典代表。两种算法都通过递归来实现,过程非常相似。归并排序非常稳定,但不是原地排序;快速排序,是原地排序算法,应用得更加广泛。

归并排序:将序列分成两个子序列,对每个子序列进行递归排序,然后将两个排好序的子序列合并成一个有序序列。
快速排序:选取一个基准元素,将小于等于基准元素的元素放到左边,大于基准元素的元素放到右边,然后对左右两个子序列递归进行快速排序。

2、写出伪代码

归并排序:

merge_sort(arr, p, r)
    if p < r
        q = (p + r) / 2
        merge_sort(arr, p, q)
        merge_sort(arr, q+1, r)
        merge(arr, p, q, r)

merge(arr, p, q, r)
    n1 = q - p + 1
    n2 = r - q
    let L[1..n1+1] and R[1..n2+1] be new arrays
    for i = 1 to n1
        L[i] = arr[p + i - 1]
    for j = 1 to n2
        R[j] = arr[q + j]
    L[n1+1] = infinity
    R[n2+1] = infinity
    i = 1
    j = 1
    for k = p to r
        if L[i] <= R[j]
            arr[k] = L[i]
            i = i + 1
        else arr[k] = R[j]
            j = j + 1

快速排序:

quick_sort(arr, low, high)
    if low < high
        pivot_location = partition(arr, low, high)
        quick_sort(arr, low, pivot_location - 1)
        quick_sort(arr, pivot_location + 1, high)

partition(arr, low, high)
    pivot_item = arr[low]
    left_mark = low + 1
    right_mark = high
    done = False
    while not done
        while left_mark <= right_mark and arr[left_mark] <= pivot_item
            left_mark += 1
        while right_mark >= left_mark and arr[right_mark] >= pivot_item
            right_mark -= 1
        if right_mark < left_mark
            done = True
        else swap arr[left_mark] with arr[right_mark]
    swap arr[low] with arr[right_mark]
    return right_mark

3、代码实现

#include <iostream>
using namespace std;

void merge(int arr[], int l, int m, int r) {
   int i, j, k;
   int n1 = m - l + 1;
   int n2 = r - m;

   int L[n1], R[n2];

   for (i = 0; i < n1; i++)
       L[i] = arr[l + i];
   for (j = 0; j < n2; j++)
       R[j] = arr[m + 1 + j];

   i = 0;
   j = 0;
   k = l;
   while (i < n1 && j < n2) {
       if (L[i] <= R[j]) {
           arr[k] = L[i];
           i++;
       }
       else {
           arr[k] = R[j];
           j++;
       }
       k++;
   }

   while (i < n1) {
       arr[k] = L[i];
       i++;
       k++;
   }

   while (j < n2) {
       arr[k] = R[j];
       j++;
       k++;
   }
}

void mergeSort(int arr[], int l, int r) {
   if (l >= r) {
       return;
   }
   int m = l + (r - l) / 2;
   mergeSort(arr, l, m);
   mergeSort(arr, m + 1, r);
   merge(arr, l, m, r);
}

int partition(int arr[], int low, int high) {
   int pivot = arr[high];
   int i = (low - 1);

   for (int j = low; j <= high - 1; j++) {
       if (arr[j] < pivot) {
           i++;
           swap(arr[i], arr[j]);
       }
   }
   swap(arr[i + 1], arr[high]);
   return (i + 1);
}

void quickSort(int arr[], int low, int high) {
   if (low < high) {
       int pi = partition(arr, low, high);
       quickSort(arr, low, pi - 1);
       quickSort(arr, pi + 1, high);
   }
}
int main() {
   // 归并排序
   cout << "归并排序" << endl;
   cout << "请输入待排序序列长度:";
   int n;
   cin >> n;
   cout << "请输入待排序序列:";
   int a[n];
   for (int i = 0; i < n; i++) {
       cin >> a[i];
   }
   mergeSort(a, 0, n - 1);
   cout << "排序后的序列为:";
   for (int i = 0; i < n; i++) {
       cout << a[i] << " ";
   }
   
   // 快速排序
   cout << endl << endl << "快速排序" << endl;
   cout << "请输入待排序序列长度:";
   
   cin >> n;
   
   cout << "请输入待排序序列:";
   
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    quickSort(a, 0, n - 1);
    cout << "排序后的序列为:";
    for (int i = 0; i < n; i++) {
        cout << a[i] << " ";
    }
    return 0;
}

4、代码详解

上述代码实现使用C语言实现了归并排序和快速排序两种分治算法

归并排序是一种分治算法,它将待排序的序列分成两个子序列,对每个子序列进行递归排序,然后将两个排好序的子序列合并成一个有序序列。具体来说,mergeSort函数实现了归并排序。mergeSort函数的参数包括待排序数组arr、数组左端点l和右端点r。如果l>=r,则返回;否则,计算中间点m=(l+r)/2,对左半部分arr[l…m]进行递归排序,对右半部分arr[m+1…r]进行递归排序,最后将左右两个排好序的子序列合并成一个有序序列。

快速排序也是一种分治算法,它选取一个基准元素,将小于等于基准元素的元素放到左边,大于基准元素的元素放到右边,然后对左右两个子序列递归进行快速排序。具体来说,partition函数实现了快速排序。partition函数的参数包括待排序数组arr、数组左端点low和右端点high。首先选取基准元素pivot=arr[high],然后从low到high-1遍历数组arr。如果arr[j]<pivot,则将arr[i]和arr[j]交换,并将i加1。最后将arr[i+1]和arr[high]交换,并返回i+1

5、用例测试

分治与减治算法实验:题目2 排序中分治法的程序设计

6、复杂度分析

  • 归并排序:将待排序序列分成若干个子序列,每个子序列都是有序的。然后再将有序子序列合并成整体有序序列。归并排序的时间复杂度为O(nlogn),空间复杂度为O(n)。
  • 快速排序:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。快速排序的时间复杂度为O(nlogn),空间复杂度为O(logn)。

当n趋近于无穷大时,归并排序和快速排序的时间复杂度都是O(nlogn)。归并排序的时间复杂度始终都是O(nlogn),而快速排序虽然最坏情况下时间复杂度为O(n^2),但平均情况下时间复杂度为O(nlogn),最坏情况发生的概率也比较小,因此应用得更加广泛 


总结

这篇文章介绍了分治法和减治法的算法设计思想,以及它们在排序问题中的应用。文章提到了许多经典的分治法和减治法的应用,例如快速排序、归并排序、堆排序等。这些排序算法都有各自的优缺点,需要根据不同的场景和需求选择合适的算法。文章还介绍了本实验的目的和内容,即通过排序中分治法的程序设计,掌握分治法和减治法在排序问题上的应用,了解不同排序算法的原理、步骤、性能和特点,能够使用高级语言实现和测试这些排序算法,并能够分析和比较它们之间的异同。文章来源地址https://www.toymoban.com/news/detail-424770.html

到了这里,关于分治与减治算法实验:题目2 排序中分治法的程序设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 算法基础15 —— 分治算法(归并排序 + 快速排序)

    算法基础15 —— 分治算法(归并排序 + 快速排序)

    分治法的基本概念、思想 分治法是一种很重要的算法。 字面解释,分治分治,分而治之。就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。 不难发现,分

    2024年02月03日
    浏览(9)
  • 【排序算法】 归并排序详解!分治思想!

    【排序算法】 归并排序详解!分治思想!

    🎥 屿小夏 : 个人主页 🔥个人专栏 : 算法—排序篇 🌄 莫道桑榆晚,为霞尚满天! ​ 什么是归并?通过归并排序就能让数据有序?分治法是怎么在归并排序上应用的?本文将对归并排序进行细致入微的讲解,庖丁解牛般让你彻底明白归并排序! 归并排序(MERGE-SORT)是建

    2024年02月08日
    浏览(10)
  • 五种基础算法小结与典型题目分享(动态规划、分治、贪心、回溯、分支限界)

    动态规划是用于解决多阶段决策问题的算法策略。它通过用变量集合描述当前情境来定义“状态”,进而用这些状态表达每个阶段的决策。 每个阶段的状态是基于前面的状态经过某种决策得到的。通过建立状态间的递推关系,并将其形式化为数学递推式,得到“状态转移方程

    2024年01月19日
    浏览(7)
  • 考研算法31天:归并排序 【归并排序,分治】

    考研算法31天:归并排序 【归并排序,分治】

    算法介绍 归并算法其过程分为三步: 1.分:递归到最下面 2.治:两个元素之间排序。 3。归:递归到最下层然后返回,从两个元素变成四个元素再排序。 如下图所示: 动态图如下: 算法题目 算法ac代码:

    2024年02月11日
    浏览(8)
  • 【算法专题】分治 - 快速排序

    做题链接 - Leetcode -75.颜色分类 题目 :给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置的 sort 函数的情

    2024年02月05日
    浏览(14)
  • 【leetcode刷题之路】剑指Offer(4)——分治+排序算法+动态规划

    8 分治算法 8.1 【递归】剑指 Offer 07 - 重建二叉树 https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof/   前序遍历是根左右,中序遍历是左根右,这也就意味着前序遍历的第一个节点是整棵树的根节点,顺着这个节点找到它在中序遍历中的位置,即为in_root,那么in_root左边的都在左子

    2024年02月11日
    浏览(13)
  • 【算法】减治法详解

    【算法】减治法详解

    分治法是将一个大问题划分为若干个子问题,分别求解后将子问题的解进行合并得到原问题的解。减治法同样是讲一个大问题划分为若干个小的子问题,但是这些子问题不需要分别求解,只需要求解其中一个子问题便可,因此也不需要对子问题进行合并,可以说,减治法是一

    2024年02月04日
    浏览(7)
  • 蓝桥杯宝藏排序题目算法(冒泡、选择、插入)

    从左往右找到最小的元素,放在起始位置;重复上述步骤,依次找到第2小、第3小元素... 第0次循环从[0,n-1]中找最小元素a[x],与a[0]交换 第1次循环从[1,n-1]中找最小元素,与a[1]交换 第2次循环从[2,n-1]中找最小元素,与a[2]交换 第i次循环从[i,n-1]中找最小元素,与a[i]交换 第n-2次循

    2024年01月17日
    浏览(7)
  • 南京邮电大学算法与设计实验二:贪心算法(最全最新,与题目要求一致)

    南京邮电大学算法与设计实验二:贪心算法(最全最新,与题目要求一致)

    三、实验原理及内容 实验原理: 1 、用贪心法实现求两序列的一般背包问题。要求掌握贪心法思想在实际中的应用,分析一般背包的问题特征,选择算法策略并设计具体算法,编程实现贪心选择策略的比较,并输出最优解和最优解值。 2 、用贪心法求解带时限的 ( 单位时间

    2024年02月05日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包