基于数组的归并排序--递归与非递归法(C++/C)

目录

递归法

非递归法


思想:分而治之:

参考网上其他的示意图

递归法

自顶向下

归并排序是建立在归并操作上的一种时间复杂度为O(nlogn),空间复杂度为O(n)有效排序算法,思想是分而治之。

// 归并排序_递归.cpp: 
// 以数组为例子

#include "stdafx.h"

#include<iostream>
using namespace std;
// 在原始数组上进行操作,将前后两个有序序列合并到一个临时数组中,并将合并后的数组复制给原始数组arr
void merge(int arr[], int low, int middle, int high)
{
	int i, j, k;
	i = low; // low为第一个有序区的第一个元素
	j = middle + 1; // middle+1为第二个有序区的第一个元素
	k = 0;
	int *temp = new(nothrow) int[high - low + 1];
	if (!temp)
	{
		cout << "内存分配失败!" << endl;
		return;
	}
	// 依次比较两个有序序列的第一个元素,将较小的一方存放到temp数组中
	while (i <= middle && j <= high)
	{
		if (arr[i] < arr[j])
			temp[k++] = arr[i++];
		else
			temp[k++] = arr[j++];
	}
	while (i <= middle)
		temp[k++] = arr[i++];
	while (j <= high)
		temp[k++] = arr[j++];
	// 将排好序的存回arr中low到high该区间内 
	for (i = low, k = 0; i <= high; i++, k++)
		arr[i] = temp[k];
	// 删除指针,由于指向的是数组,必须用delete [] 
	delete[]temp;

}
void mergeSort(int arr[], int low, int high)
{
	// 用递归应用二路归并函数实现排序——分治法
	if (low < high)  //(是if,不是while!,且不含等号!否则死循环!)
	{
		int mid = (low + high) / 2;
		mergeSort(arr, low, mid);
		mergeSort(arr, mid + 1, high);
		merge(arr, low, mid, high);
	}
        else
            return;
}
int main()
{
	int x[] = { -3,5,7,-7,4,1,0,9};
	int n = sizeof(x) / sizeof(int);
	mergeSort(x, 0, n-1);
	for (int i = 0; i<8; i++)
		cout << x[i] << " ";
	return 0;
}

非递归法

自底向上

合并函数与递归法的合并函数一样,都是非递归实现的

#include<iostream>
using namespace std;
// 在原始数组上进行操作,
void merge(int arr[], int low, int middle, int high)
{
	int i, j, k;
	i = low; // low为第一个有序区的第一个元素
	j = middle + 1; // middle+1为第二个有序区的第一个元素
	k = 0;
	int *temp = new(nothrow) int[high - low + 1];
	if (!temp)
	{
		cout << "内存分配失败!" << endl;
		return;
	}
	// 依次比较两个有序序列的第一个元素,将较小的一方存放到temp数组中
	while (i <= middle && j <= high)
	{
		if (arr[i] < arr[j])
			temp[k++] = arr[i++];
		else
			temp[k++] = arr[j++];
	}
	while (i <= middle)
		temp[k++] = arr[i++];
	while (j <= high)
		temp[k++] = arr[j++];
	// 将排好序的存回arr中low到high该区间内 
	for (i = low, k = 0; i <= high; i++, k++)
		arr[i] = temp[k];
	// 删除指针,由于指向的是数组,必须用delete [] 
	delete[]temp;

}

非递归合并排序函数:

根据步长size大小先处理数组中两两相邻的序列,合并后成倍扩大size,进入下一轮的合并排序

void mergeSort(int arr[], int n)
{
    // 非递归法实现归并排序, 形参n表示为数组中的元素个数
    int size = 1, low, middle, high;
    while (size <= n)
    {
        low = 0;
        while (low + size <= n)
        {
            middle = low + size - 1;
            high = middle + size;
            if (high > n)
                high = n;
            merge(arr, low, middle, high);
            low = high + 1;
        }
        size *= 2;
    }

}
int main()
{
    int x[] = { -3,5,7,-7,4,1,0,9,-1};
    int n = sizeof(x) / sizeof(int);
    mergeSort(x, n-1);
    for (int i = 0; i <= n; i++)
        cout << x[i] << " ";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Doutd_y/article/details/82015102
今日推荐