分治法

本文详细介绍了分治策略的基本思想及应用,并通过归并排序这一经典算法深入解析了分治策略的具体实现过程。文章首先阐述了分治策略的概念,随后通过归并排序实例展示了如何将一个大问题分解为若干个小问题来解决,并最终合并这些小问题的解以获得原问题的答案。
摘要由CSDN通过智能技术生成

一、算法描述

           分治策略:将原问题划分n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,得到原问题的解。字面上的解释就是“分而治之”。

  • “分” 将问题分解为规模更小的子问题;
  • “治” 将这些规模更小的子问题逐个击破;
  • “合” 将已解决的子问题合并,最终得出“母”问题的解;

       分治模式在每一层递归上都有三个步骤:

       1、分解:将原问题分解成一系列子问题;

       2、解决:递归地解各子问题。若子问题足够小,则直接求解;

       3、合并:将子问题的结果合并成原问题的解。

     MERGE(A, p, q, r)
         n1 <- q - p + 1
         n2 <- r-q
         // creat arrays L[1..n1 + 1] and R[1..n2 + 1]
         for i <- 1 to n1
              do L[i] <- A[p + i -1]
         for j <- 1 to n2
              do R[i]<- A[q + j]
         L[n1 + 1] <- “sentinel card”  // 避免检测堆空, 引入“哨兵牌”。
         R[n2 + 1] <- “sentinel card”
         i <- 1
         j <- 1
         for k <- p to r
             do if L[i] <= R[j]
                   then A[k] <- L[i]
                    i <- i + 1
                   else A[k] <- R[j]
                    j <- j + 1

      合并排序(归并排序)算法完全依照上述模式:
      1、分解:将n个元素分成各含n/2个元素的子序列;
      2、解决:用合并排序法对两个子序列递归地排序;
      3、合并:合并两个已排序的子序列以得到排序结构。

    MERGE-SORT(A, p, r)
        if p < r
           then q <- [(p + r) / 2]
           MERGE-SORT(A, p, q)
           MERGE-SORT(A, q + 1, r)
           MERGE(A, p, q, r)


二、算法实现(归并排序)

void Merge(int* pDataArray, int nLpos, int nRpos, int nRend)
{
	const int MaxInt = 32767;
	int i, j, n;
	int nLeftLen = nRpos - nLpos + 1;
	int nRightLen = nRend - nRpos;
	int *pLArray = (int *)malloc( (nLeftLen + 1) * sizeof(int));
	int *pRArray = (int *)malloc( (nRightLen + 1) * sizeof(int));

	for (i = 0; i < nLeftLen; i++)
	{
	    *(pLArray + i) = *(pDataArray + nLpos + i);
	}
	for (j = 0; j < nRightLen; j++)
	{
	    *(pRArray + j) = *(pDataArray + nRpos + j + 1);
	}

	*(pLArray + nLeftLen) = MaxInt;
    *(pRArray + nRightLen) = MaxInt;

	i = 0;
	j = 0;

    for(n = nLpos; n <= nRend; n++)
	{
	    if(*(pLArray + i) <=  *(pRArray + j))
		{
		   *(pDataArray + n) = *(pLArray + i);
		   i++;
		}
		else
		{
		   *(pDataArray + n) = *(pRArray + j);
		   j++;
		}
	}

 	free(pLArray);
 	free(pRArray);
}

void MergeSort(int* pDataArray, int nLeft, int nRight)
{
	int nMid;
	if(nLeft >= nRight)
	{
	   return ;
	}
	else
	{
	   nMid = (nLeft + nRight) / 2;
	   MergeSort(pDataArray, nLeft, nMid);
	   MergeSort(pDataArray, nMid + 1, nRight);
	   Merge(pDataArray, nLeft, nMid, nRight);
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值