【算法】二路歸併遞歸與非遞歸思想

(一)公共函數

   1.1 頭文件:

#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <iterator>
#include <time.h>
#include <string>
#include <math.h>
#include <utility>
#include <algorithm>
using namespace std;

   輸出函數:

template<class Type>
void Print(Type* ar, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << ar[i] << " ";
	}
	cout << endl;
}

(二)遞歸思想

    2.1 思想描述

                         

    2.2 代碼實現

template<class Type> //合併函數
void Merge(Type* br, Type* ar, int part, int left, int right)
{
	int i = left, j = part + 1, index = i;
	while (i <= part && j <= right)
	{
		br[index++] = ar[i] < ar[j] ? ar[i++] : ar[j++];
	}

	while (i <= part)
	{
		br[index++] = ar[i++];
	}

	while (j <= right)
	{
		br[index++] = ar[j++];
	}
}

template<class Type> //數據排序後保留函數
void Copy(Type* des, Type* sou, int left, int right)
{
	for (int i = left; i <= right; i++)
	{
		des[i] = sou[i];
	}
}


template<class Type>//分段函數
void PassMerge(Type* br, Type* ar, int left, int right)
{
	if (left < right)
	{
		int part = (right - left) / 2 + left;
		PassMerge(br, ar, left, part);
		PassMerge(br, ar, part + 1, right);
		Merge(br, ar, part, left, right);
		Copy(ar, br, left, right);
	}
}

template<class Type> //遞歸實現二路歸併
void MergeSort(Type* ar, int len)
{
	Type* br = new Type[len];
	PassMerge(br, ar, 0, len - 1);
	delete []br;
}

(三)非遞歸思想

3.1 思想描述

      利用每次數據段的寬度的數字表達式來控制調整元素使之有序,合併代碼和遞歸代碼是相同的;

3.2 代碼實現

template<class Type> //合併函數
void Merge(Type* br, Type* ar, int part, int left, int right)
{
	int i = left, j = part + 1, index = i;
	while (i <= part && j <= right)
	{
		br[index++] = ar[i] < ar[j] ? ar[i++] : ar[j++];
	}

	while (i <= part)
	{
		br[index++] = ar[i++];
	}

	while (j <= right)
	{
		br[index++] = ar[j++];
	}
}

template<class Type>//分段函數
void NicePassMerge(Type* des, Type* sou, int width, int len)
{
	int i = 0;
	for (; i + 2 * width - 1 <= len - 1; i += 2 * width)
	{
		Merge(des, sou, i + width - 1, i, i + 2 * width - 1);
	}

	if (len - 1 > i + width - 1)//處理剩餘的元素不足的情況
	{
		Merge(des, sou, i + width - 1, i, len - 1);
	}
	else
	{
		for (int j = i; j < len; j++)
		{
			des[j] = sou[j];
		}
	}
}

template<class Type> //非遞歸實現二路歸併
void NiceMergeSort(Type* ar, int len)
{
	Type* br = new Type[len];
	int width = 1;
	while (width < len)
	{
		NicePassMerge(br, ar, width, len);
		width += width;
		NicePassMerge(ar, br, width, len);
		width += width;
	}
	delete []br;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章