• 算法与数据结构第六次作业——排序


    算法与数据结构实验题 5.12 Bubble Sort

    ★实验任务 给定一个 1~N 的排列P ,即1到N中的每个数在P中都出现一次。

    现在要对排列P进行冒泡排序,代码如下:

    for (int i = 1; i <= N; ++i)
      for (int j = N, t; j > i; ‐‐j)
        if (P[j ‐ 1] > P[j])
          t = P[j], P[j] = P[j ‐ 1], P[j ‐ 1] = t;
    

    在排序过程中,数字的位置可能会发生变化。对于1~N的每个数字,你需要输出过程中达到的最左位置下标和最右位置下标的差的绝对值。

    80%的数据:N<=1000

    100%的数据:N<=100000

    输入示例
    4
    3 2 1 4
    输出示例
    2 1 2 0
    Hint
    

    样例冒泡排序过程:

    swap 2 1: 3 2 1 4 ­> 3 1 2 4
    
    swap 3 1: 3 1 2 4 ­> 1 3 2 4
    
    swap 3 2: 1 3 2 4 ­> 1 2 3 4
    

    这道题目的破题点在于如何将每个数字到达的最左侧和最右侧的位置找到。需要自己多模拟几次过程,就可以发现:每个数字到达的最右侧位置,其实就是看这个数字的右侧有几个比他小的数字,而最左侧位置就取初始位置和排序完成后的位置中较小的那一个。
    考虑到数据的大小,需要采用归并的思想来解答。

    • 初版代码(采用冒泡模拟的方法,数据较大的点超时)
    #include<iostream>
    using namespace std;
    int main()
    {
    	int n;
    	cin >> n;
    	int* a = new int[n];
    	int* b = new int[n];
    	int* min = new int[n];
    	int* max = new int[n];
    	for (int i = 0; i < n; i++)
    	{
    		cin >> a[i];
    		b[i] = a[i];
    		min[a[i] - 1] = i;
    		max[a[i] - 1] = i;
    	}
    	for (int i = n-1; i >= 0; i--)
    	{
    		for (int j = 0,t; j < i; j++)
    		{
    			if (a[j] > a[j+1])
    			{
    				 t = a[j], a[j] = a[j + 1], a[j + 1] = t;
    				if (max[a[j] - 1] < j) max[a[j] - 1] = j;
    				if (min[a[j] - 1] > j) min[a[j] - 1] = j;
    				if (max[a[j + 1] - 1] < j+1) max[a[j + 1] - 1] = j+1;
    				if (min[a[j + 1] - 1] > j+1) min[a[j + 1] - 1] = j+1;
    
    			}
    		}
    	}
    
    	for (int i = 0; i < n; i++)
    	{
    		int pos = max[i] - min[i];
    		cout << pos << ' ';
    
    	}
    }
    
    • 归并做法(与归并排序类似)
    #include<iostream>
    #include<cstdio>
    using namespace std;
    int Right[100001] = { 0 };
    int Left[100001] = { 0 };
    int Pos[100001] = { 0 };
    void merge(int a[], int left, int mid, int right)
    {
    	int l_pos = left;
    	int r_pos = mid+1;
    	int pos = left;
    	int sum = 0;
    	for (int i = left; i <= mid; i++)
    	{
    		Left[i] = a[i];
    	}
    	for (int i = mid+1; i <= right; i++)
    	{
    		Right[i] = a[i];
    	}
    	while (l_pos <= mid && r_pos <= right)
    	{
    		if (Left[l_pos] > Right[r_pos])
    		{
    			sum++;
    			a[pos++] = Right[r_pos++];
    		}
    		else
    		{
    			Pos[Left[l_pos]] += sum;
    			a[pos++] = Left[l_pos++];
    		}
    	}
    	while (l_pos <= mid)
    	{
    		Pos[Left[l_pos]] += sum;
    		a[pos++] = Left[l_pos++];
    	}
    	while (r_pos <= right)
    	{
    		a[pos++] = Right[r_pos++];
    	}
    }
    void msort(int a[], int left, int right)
    {
    	if (left < right)
    	{
    		int mid = (left + right) / 2;
    		msort(a, left, mid);
    		msort(a, mid + 1, right);
    		merge(a, left, mid, right);
    	}
    	
    
    }
    int min(int a, int b)
    {
    	if (a > b) return b;
    	else return a;
    }
    int main()
    {
    	int a[100001]; int b[100001];
    	int n;
    	cin >> n;
    	for (int i = 1; i <= n; i++)
    	{
    		scanf_s("%d", &a[i]);
    		b[a[i]] = i;
    	}
    	msort(a, 1, n);
    	for (int i = 1; i <= n; i++)
    	{
    		cout << b[i] + Pos[i] - min(i, b[i])<<' ';
    	}
    }
    
  • 相关阅读:
    【体验】在Adobe After Effects CC 2018中使用脚本创建窗口
    flask中错误使用flask.redirect('/path')导致的框架奇怪错误
    01-复杂度2 Maximum Subsequence Sum
    01-复杂度1 最大子列和问题
    02-线性结构1 两个有序链表序列的合并
    bfs—迷宫问题—poj3984
    bfs—Dungeon Master—poj2251
    bfs—Catch That Cow—poj3278
    GPTL—练习集—006树的遍历
    DB2存储过程——参数详解
  • 原文地址:https://www.cnblogs.com/wangmou-233-1024-com/p/13834464.html
Copyright © 2020-2023  润新知