《算法》第二章——归并排序实现,快速归并,间接(索引)归并

#include<iostream>
#include<algorithm>
#define N 5
using namespace std;

int aux[N];//辅助数组

void merge(int a[],int lo,int mid,int hi)
{//将a[lo..mid]和a[mid+1..hi]归并
	int i = lo;
	int j = mid + 1;
	for (int k = lo; k <=hi; k++)//将a[lo..hi]复制到aux[lo..hi]
	{
		aux[k] = a[k];
	}
	for (int k=lo; k <=hi; k++)//归并到a[lo..hi]
	{
		if (i > mid)
			a[k] = aux[j++];//左半边用尽(取右半边元素)
		else if (j > hi)
			a[k] = aux[i++];//右半边用尽(取左半边元素)
		else if (aux[i] > aux[j])
			a[k] = aux[j++];//取左右半边中较小的那个元素
		else
			a[k] = aux[i++];//取左右半边中较小的那个元素

	}
}

//自顶向下归并
void sort_TopDown(int a[],int lo,int hi)
{
	if (lo >= hi)
		return;
	int mid = (lo + hi) / 2;
	sort_TopDown(a, lo, mid);
	sort_TopDown(a,mid + 1, hi);
	if (a[mid] > a[mid + 1])//如果a[mid]小于等于a[mid+1]则数组已有序,所以跳过merge操作
		merge(a, lo, mid, hi);
}

//自底向上归并
void sort_DownTop(int a[])
{
	for (int size = 1; size < N; size+=size)
	{
		for (int i = 0; i < N - size; i+=size*2)
		{
			merge(a, i, i + size - 1, min(i + size - 1 + size, N - 1));//因为最后一部分的大小可能小于一个size,此时赢取N-1作为hi值
		}
	}
}

int main()
{
	int a[N];
	for (int i = 0; i < N; i++)
		cin >> a[i];
	sort_TopDown(a, 0, N-1);
	sort_DownTop(a);
	for (int i = 0; i < N; i++)
		cout << a[i] << " ";
	
	cout << endl;
	system("pause");
}


快速归并


int aux[N];
//快速归并
void q_mergesort(int a[],int low,int mid,int high)
{
	for (int i = 0; i <= mid; i++)
	{//顺序拷贝前半部分
		aux[i] = a[i];
	}
	for (int i = mid + 1; i <= high; i++)
	{//逆序拷贝后半部分
		aux[i] = a[high - i + mid + 1];
	}
	for (int k = low; k <= high; k++)
	{
		int i=low, j=high;
		if (aux[j] < aux[i])
		{
			a[k] = aux[j--];
		}
		else
		{
			a[k] = aux[i++];
		}
	}
}
因为这种改进算法是两个索引从两边向中间扫描所以即使越界也不会重复扫描。

索引归并


#include<iostream>
#define N 5
using namespace std;

void merge(int a[], int aux[], int index[], int lo, int mid, int hi)
{
	for (int i = lo; i <= hi; i++)
	{
		aux[i] = index[i];
	}

	int i = lo;
	int j = mid+1;
	for (int k = lo; k <= hi; k++)
	{//这里扫描的是辅助数组aux然后将结果归并到index数组中
		if (i > mid)
		{
			index[k] = aux[j++];
		}
		else if (j > hi)
		{
			index[k] = aux[i++];
		}
		else if (a[aux[i]] < a[aux[j]])
		{
			index[k] = aux[i++];
		}
		else
		{
			index[k] = aux[j++];
		}
	}
}

void index_sort(int a[],int aux[],int index[],int lo,int hi)
{
	if (hi <= lo)
		return;
		
	int mid = (lo + hi) / 2;
	index_sort(a, aux, index, lo, mid);
	index_sort(a, aux, index, mid + 1, hi);
	merge(a, aux, index, lo, mid, hi);
}

int main()
{
	int a[N];//带排序数组
	int aux[N];//辅助数组用了存索引
	int index[N];//索引数组

	for (int i = 0; i < N; i++)
	{
		cin >> a[i];
		index[i] = i;//初始化索引数组使得a[i]=a[index[i]]
	}
	index_sort(a, aux, index, 0, N - 1);
	for (int i = 0; i < N; i++)
	{
		cout << index[i] << " ";
	}
	system("pause");
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值