深圳大学计软《数据结构》实验16--内部排序3

问题 A: DS内排—2-路归并排序

题目描述

输入一组字符串,用2-路归并排序按字典顺序进行降序排序。

输入

测试次数t

每组测试数据:数据个数n,后跟n个字符串,字符串不含空格。

输出

对每组测试数据,输出2-路归并排序的每一趟排序结果。每组测试数据的输出之间有1空行。

样例输入

2
6 shenzhen beijing guangzhou futian nanshan baoan
10 apple pear peach grape cherry dew fig haw lemon marc

样例输出

shenzhen beijing guangzhou futian nanshan baoan
shenzhen guangzhou futian beijing nanshan baoan
shenzhen nanshan guangzhou futian beijing baoan

pear apple peach grape dew cherry haw fig marc lemon
pear peach grape apple haw fig dew cherry marc lemon
pear peach haw grape fig dew cherry apple marc lemon
pear peach marc lemon haw grape fig dew cherry apple

AC代码

#include<iostream>
#include<vector>
using namespace std;

void print_string(vector<string>& arr) {
	int len = arr.size() - 1;
	for (int i = 1; i < len; i++)
		cout << arr[i] << " ";
	cout << arr[len] << endl;
}


void Merge(vector<string>& Key, vector<string>& Data, int left, int mid, int right)
{
	int i = left, j = mid + 1, k = left;
	while (i <= mid && j <= right) {  
		if (Key[i] >= Key[j])  Data[k++] = Key[i++];
		else  Data[k++] = Key[j++];
	}
	while (i <= mid) { Data[k++] = Key[i++]; }
	while (j <= right) { Data[k++] = Key[j++]; }
}

void MergeSort(vector<string>& Key, vector<string>& Data)
{
	int len = Key.size() - 1;
	int left, mid, right, step;
	for (step = 1; step < len; step *= 2) {
		for (left = 1; left <= len; left += 2 * step) {
			mid = left + step - 1;   
			if (mid >= len) break;  
			right = left + 2 * step - 1;
			if (right > len)
				right = len;
			Merge(Key, Data, left, mid, right);
		}
		for (int t = 1; t <= len; t++) Key[t] = Data[t];
		print_string(Key);
	}
}


int main() {
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		if (i)
			cout << endl;
		int len;
		cin >> len;
		vector<string>key(len + 1);
		vector<string>data(len + 1);
		for (int i = 1; i <= len; i++)
			cin >> key[i];
		MergeSort(key, data);
	}
	return 0;
}

问题 B: 基数排序(内部排序)

题目描述

给定一组数据,对其进行基数升序排序。

输入

测试次数t

每组测试数据一行:数字个数n,后跟n个数字(整数)

注:如果序列中有负数,则每个数字加上最小负数的绝对值,使序列中的数均大于等于0。排序后再减去最小负数的绝对值。

输出

对每组测试数据,输出每趟分配、收集的结果。若分配中该位没有数字,输出NULL。具体输出格式见样例。每组测试数据间以空行分隔。

如果序列中有负数,最后输出减去最小负数绝对值的序列值。

样例输入

2
10 278 109 63 930 589 184 505 269 8 83
6 57 0 93 19 18 99

样例输出

0:->930->^
1:NULL
2:NULL
3:->63->83->^
4:->184->^
5:->505->^
6:NULL
7:NULL
8:->278->8->^
9:->109->589->269->^
930 63 83 184 505 278 8 109 589 269
0:->505->8->109->^
1:NULL
2:NULL
3:->930->^
4:NULL
5:NULL
6:->63->269->^
7:->278->^
8:->83->184->589->^
9:NULL
505 8 109 930 63 269 278 83 184 589
0:->8->63->83->^
1:->109->184->^
2:->269->278->^
3:NULL
4:NULL
5:->505->589->^
6:NULL
7:NULL
8:NULL
9:->930->^
8 63 83 109 184 269 278 505 589 930

0:->0->^
1:NULL
2:NULL
3:->93->^
4:NULL
5:NULL
6:NULL
7:->57->^
8:->18->^
9:->19->99->^
0 93 57 18 19 99
0:->0->^
1:->18->19->^
2:NULL
3:NULL
4:NULL
5:->57->^
6:NULL
7:NULL
8:NULL
9:->93->99->^
0 18 19 57 93 99

AC代码

#include<bits/stdc++.h>
using namespace std;


class Problem
{
public:
	Problem();
	void RadixSort();
private:
	int len;
	int deviation;//如有负数,用来记录最小负数,作为偏差量。最后的结果必须加上此量。
	vector<int>v;
	list<int>q[10];//收集队列
	int bits;//最大位数
	void display_queue();
	void display_arr();
	void collect();
	void distribute(int i);
};

Problem::Problem()
{
	deviation = 0;
	bits = 0;
	cin >> len;
	v.resize(len);
	for (int i = 0; i < len; i++)
	{
		cin >> v[i];
		deviation = min(deviation, v[i]);
	}

	if (deviation)
		for (int i = 0; i < len; i++)
		{
			v[i] -= deviation;
		}

	for (int i = 0; i < len; i++)
		bits = max(bits, (int)to_string(v[i]).length());

}


void Problem::display_arr() {
	for (int i = 0; i < len; i++)
	{
		if (i)
			cout << " ";
		cout << v[i];
	}
	cout << endl;
}

void Problem::display_queue()
{
	for (int i = 0; i < 10; i++)
	{
		cout << i << ":";
		if (q[i].empty())
		{
			cout << "NULL" << endl;
			continue;
		}

		for (auto it = q[i].begin(); it != q[i].end(); it++)
		{
			cout << "->" << *it;
		}
		cout << "->^" << endl;
	}
}


void Problem::collect()
{
	v.clear();
	for (int i = 0; i < 10; i++)
	{
		for (int& it : q[i])
		{
			v.push_back(it);
		}
		q[i].clear();
	}

}


void Problem::distribute(int cur_bits)
{

	for (int i = 0; i < len; i++)
	{
		string s = to_string(v[i]);
		if (s.length() < cur_bits)
			q[0].push_back(v[i]);
		else
			q[s[s.length() - cur_bits] - '0'].push_back(v[i]);
	}
}

void Problem::RadixSort()
{
	for (int i = 1; i <= bits; i++)
	{
		distribute(i);
		display_queue();
		collect();
		display_arr();
	}
}

int main() {
	int n;
	cin >> n;
	while (n--)
	{
		Problem p;
		p.RadixSort();
		if (n)
			cout << endl;
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹无悔

请支持我的梦想!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值