【算法设计与分析】4、合并排序

/**
* 书本:《算法分析与设计》
* 功能:给定线性序列集合中n个元素和一个整数k,1<=k<=n,输出者n个元素中第“k小”元素的值和位置
* 文件:lesson4.cpp
* 时间:2014年11月16日13:41:04
* 作者:cutter_point
*/
#include <iostream>

using namespace std;

/*
*1、实现这个算法首先肯定是要排序
*2、排好序之后第k个就是第k小的了
*3、再根据找出来的数据,回到原来的数组中找到原来的位置
*/
void paiXu(int *a, int *b, int left, int right, int mid);	//前向声明

//由于是吧b先排序排好,然后放回到a中,吧原来的数据覆盖所以得有一个吧b拷贝到a的过程
void copy(int *a, int *b, int left, int right)
{
	for (int i = left; i <= right; ++i)
	{
		a[i] = b[i];
	}
}

//使用合并排序对数组进行排序
void heBin(int *a, int left, int right)
{
	int *b = new int[sizeof(a) / sizeof(*a)];
	//首先这个算法至少得有两个元素吧
	if (left < right)
	{
		*b = { 0 };
		//去中点,一直取中点,直到剩下2个元素合并排序
		int mid = (left + right) / 2;
		//对这两边进行排序合并
		heBin(a, left, mid);
		heBin(a, mid + 1, right);

		/*
		cout<<endl;
		cout<<mid<<"--------------"<<endl;
		*/
		paiXu(a, b, left, right, mid);	//最后一道paiXu出问题了!!解决:由于是吧b先排序排好,然后放回到a中,吧原来的数据覆盖所以得有一个吧b拷贝到a的过程
		/*
		cout<<endl;
		for(int i = 0; i < 10 ; ++i)
		{
		cout<<b[i]<<' ';
		}
		*/
		copy(a, b, left, right);
	}
}

//这里有一个合并排序的核心算法
void paiXu(int a[], int *b, int left, int right, int mid)
{
	int rb = mid + 1;	//右边集合的开始
	int i = left, j = left;	//这个i和j一个是左边集合的起始,一个是b数组的计数器
	while (i <= mid && rb <= right)	//两边一起开始比较,合并排序,如果有一边满了,其余的直接按顺序拍下去就可以了
	{
		if (a[i] <= a[rb])	//左边集合的数据依次和右边的数据比较
			b[j++] = a[i++];	//把左边对应的数据先放到b中,然后向后推移一位
		else
			b[j++] = a[rb++];	//把左边对应的数据先放到b中,然后向后推移一位
	}

	//排序完成后剩下的继续
	//如果是左边的排完了,把右边剩下的排完
	if (i > mid)
	{
		for (int q = rb; q <= right; ++q)	//把右边剩下的全部拍到后面去
			b[j++] = a[q];
	}
	else
	{
		//右边的排完了,把左边的剩下的排完
		for (int q = i; q <= mid; ++q)
			b[j++] = a[q];

	}
}

//排序完成后输出要输出的数据
//1、原来的数组
//2、排好序的数组
//3、输出相应的数值和位置
void show(int *a, int *b, int k, int n)
{
	//a是原始数组,b是排好序的数组,k是要找的第k小的数,一共n个数
	/*
	int xunZhao = 0;
	cout << "原来的数组是:" << endl;
	for (int a1 = 0; a1 < n; ++a1)
	{
	cout << a[a1] << ' ';
	}
	*/
	//输出新的数组
	cout << endl << "排好序的数组是:" << endl;
	for (int a2 = 0; a2 < n; ++a2)
	{
		cout << a[a2] << ' ';
	}
	int xunZhao = 0;

	while (a[k - 1] != b[xunZhao])
	{
		++xunZhao;
	}

	cout << endl << "第 " << k << " 小的数是:" << a[k - 1] << " 原位置是:" << xunZhao + 1 << endl;

}

int main()
{
	char c;
	int k, n;


	int a[] = { 1, 2, 4, 3, 7, 5, 6, 8, 9, 10 };
	int b[] = { 1, 2, 4, 3, 7, 5, 6, 8, 9, 10 };
	n = 10;

	cout << "原来的数组是:" << endl;
	for (int a1 = 0; a1 < n; ++a1)
	{
		cout << b[a1] << ' ';
	}

	while (true)
	{
		heBin(a, 0, 9);

		cout << endl << "你想知道第几小的数?" << endl;
		cin >> k;
		show(a, b, k, n);
	}

	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值