归并排序 MergeSort (设置哨兵)

归并排序

  1. 基本思路
    归并排序使用分治的思想,每次将数据集分为前后两个部分,直到规模缩减为一,开始合并;合并时通过申请的空间,遍历两个子数据集,将每一个数据从小到大插入,最后将临时数据复制回原序列,直到最后一次得到完整的序列。

  2. 算法

MERGE(array, begin1, begin2, end):
	n1 = begin2-beign1
	n2 = end-begin2+1
	temp1[n1+1] = MAX
	temp2[n2+1] = MAX
	for i-n1
			temp1[i] = array[begin1+i]
	for i-n2
			temp[i] = array[begin2+i]
	i=0, j=0
	for begin1-end
			if temp1[i]<temp2[j]
				array[begin1] = temp1[i]
				begin1++
			else
				array[begin1] = temp2[j]
				begin1++

解释:算法中申请了两个临时的数组,temp1,temp2,分步存放当前数据集的前后两部分(注意它们分别多申请了一个空间存放某个最大值,用作哨兵),之后进行循环,将temp中的数据从小到大插回原序列。

MERGESORT (array, begin, end):
	if begin<end:
			mid = (begin+end)/2
			MERGESORT (array, begin, mid)
			MERGESORT (array, mid+1, end)
			MERGE (array, begin, mid+1, end)
			

解释:先递归地分解,然后合并

  1. 复杂度:O(nlogn)

  2. 运行截图
    在这里插入图片描述

  3. 源代码

#include <iostream>
#include <vector>
#include <ctime>
#include <climits>
using namespace std;
//合并 
void Merge(vector<int> &list, int begin1, int begin2, int end);
//归并排序
void MergeSort(vector<int> &list, int begin, int end);
//得到随机序列
void GetRandList(vector<int> &list, int n);
//打印
void Print(const vector<int> &list);

int main(int argc, char** argv) {
	vector<int> list;
	GetRandList(list,20);
	Print(list);
	MergeSort(list,0,list.size()-1);
	Print(list);
	return 0;
}
void Merge(vector<int> &list, int begin1, int begin2, int end)
{
	int n1 = begin2-begin1;
	int n2 = end-begin2+1;
	vector<int> temp1;
	vector<int> temp2;
	temp1.resize(n1+1);
	temp2.resize(n2+1);	
	temp1[n1] = INT_MAX;
	temp2[n2] = INT_MAX;
	for(int i=0;i<n1;i++)
	{
		temp1[i] = list[begin1+i];
	}
	for(int i=0;i<n2;i++)
	{
		temp2[i] = list[begin2+i];
	}
	int i=0;
	int j=0;
	for(int p=begin1;p<=end;p++)
	{
		if(temp1[i]<=temp2[j])
			list[p] = temp1[i++];
		else
			list[p] = temp2[j++];
	}
}

void MergeSort(vector<int> &list, int begin, int end)
{
	if(begin<end)
	{
		int mid = (begin+end)/2;
		MergeSort(list,begin,mid);
		MergeSort(list,mid+1,end);
		Merge(list,begin,mid+1,end);
	}
}

void GetRandList(vector<int> &list, int n)
{
	list.resize(n);
	for(int i=0;i<n;i++)
	{
		list[i] = rand()%n;
	}
}

void Print(const vector<int> &list)
{
	for(int i=0;i<list.size();i++)
	{
		cout<<list[i]<<" ";
	}
	cout<<endl;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归并排序是一种稳定的排序算法,它可以用于升序或降序排序。下面是一个示例代码,演示了如何使用归并排序算法来实现升序和降序排序: ```cpp #include <iostream> #include <vector> // 合并两个有序数组 void merge(std::vector<int>& arr, int left, int mid, int right, bool ascending) { int n1 = mid - left + 1; int n2 = right - mid; std::vector<int> L(n1), R(n2); for (int i = 0; i < n1; i++) { L[i] = arr[left + i]; } for (int j = 0; j < n2; j++) { R[j] = arr[mid + 1 + j]; } int i = 0, j = 0, k = left; // 升序排序 if (ascending) { while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } } // 降序排序 else { 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(std::vector<int>& arr, int left, int right, bool ascending) { if (left < right) { int mid = left + (right - left) / 2; mergeSort(arr, left, mid, ascending); mergeSort(arr, mid + 1, right, ascending); merge(arr, left, mid, right, ascending); } } // 打印数组函数 void printArray(const std::vector<int>& arr) { for (int i = 0; i < arr.size(); i++) { std::cout << arr[i] << " "; } std::cout << std::endl; } int main() { std::vector<int> arr = {5, 2, 8, 4, 1}; std::cout << "原始数组: "; printArray(arr); // 使用归并排序进行升序排序 mergeSort(arr, 0, arr.size() - 1, true); std::cout << "升序排序结果: "; printArray(arr); // 使用归并排序进行降序排序 mergeSort(arr, 0, arr.size() - 1, false); std::cout << "降序排序结果: "; printArray(arr); return 0; } ``` 在上面的代码中,`merge` 函数用于合并两个有序数组。`mergeSort` 函数使用归并排序算法对数组进行排序。通过传递 `true` 或 `false` 给 `ascending` 参数,可以设置排序的升序或降序。`printArray` 函数用于打印数组的元素。 注意:这只是一个简单的示例代码,为了方便理解,数组元素直接在代码中定义。在实际应用中,你可能需要修改代码以适应不同的输入方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值