数据结构学习第12篇 - 分治法和贪心法

本文探讨了如何使用分治法解决逆序对问题,通过归并排序算法在O(n*logn)的时间复杂度内计算逆序对数量。同时,文章介绍了贪心算法在最优合并问题中的应用,通过构建堆来找到每次最优的合并顺序,以减少比较次数。实验结果表明,这两种方法均达到了预期效果。
摘要由CSDN通过智能技术生成

分治法与贪心法

 (1)逆序对问题

设A[1,….n]是一个包含n个不同非负整数的数组。若果i<j的情况下,有A[i]>A[j],则(A[i],A[j])就称为A中的一个逆序对。请设计一个时间复杂度不超过O(n*lgn)的算法并编程实现,统计任意长度的数组A中全部逆序对的个数。

(2)最优合并问题

给定k个有序序列s1 , s2,... , sk , 用2路合并算法将这k个序列合并成一个序列。假设所采用的2路合并算法合并2个长度分别为m和n的序列需要m + n -1次比较。试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少(要求输出相应的合并顺序)。


上机12    逆序对问题

 

—、分治法

2、算法思想

     可以使用分治法解决上面问题。具体如下:利用归并方法给序列排序,将n个元素划分为n 个子序列,相邻的两个子序列进行规并操作:

  1. 如果前一个子序列a1第一个元素大于后一个子序列a2第一个元素时,把a1的第一个元素放到归并序列中,同时把a1序列的第一个元素下标加1和归并子序列的最后一个元素下标加一。
  2. 如果前一个子序列a1第一个元素小于后一个子序列a2第一个元素时,把a2的第一个元素放到归并序列中,同时把a2序列的第一个元素下标加1和归并子序列的最后一个元素下标加1,还有的是通过a1的最后一个元素的下标减第一个元素的下标得出a1目前子序列的长度,用计数器(初始为0)记录该a1长度,并把每次的记录累加。

依次进行每一对子序列归并操作。操作完成后,把该归并后的新的子序列再进行归并操作,直到规模子序列数量只剩下1个。

 

  1. 实现代码及运行结果  

程序源代码如下

#include <stdio.h>

 

#define LEN 100 //宏定义数组的大小

 

int tmp[LEN] = {};

 

int n;

 

int counter = 0;

 

void _mergeSort(int * array, int start, int middle, int end)

{

int i, j, k;

int second = middle + 1; //第二个子序列开始的下标

int first = start; //第一个子序列开始的下标

int index = start; //tmp数组开始的下标

while(first <= middle && second <= end)

{

if(array[first] <= array[second])

{

tmp[index] = array[first];

first++;

index++;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值