排序碎碎念(五):数据结构基础— Sort with Swap(0, i)

这是这道题目是一个表排序的问题,也就是(cycle sort)可以去Google搜索一下,有更多的资料。可以参考一下其他的资料,比如:

https://en.wikipedia.org/wiki/Cycle_sort 

https://www.geeksforgeeks.org/an-in-place-algorithm-for-string-transformation/

你也可以看一下讲解 点击打开链接 http://zhuanlan.zhihu.com/p/34666883

在学表排序的时候,主要学了两部分, 一:怎么构建表; 二:怎么利用构建好了额的表实现物理存储的改变;

也可以参考一下这位大神 - - 点击打开链接 https://www.liuchuo.net/archives/2301

A      [0]    [1]   [2]   [3]   [4]   [5]   [6]   [7] 

key    f      d      c      a      g      b     h      e

table 3       5     2       1      7      0      4      6 

意思是:A[0]的真实的值是 A [ table [0]  ] = A[ 3 ] = a;

在这道题目中,输入可以直接拿来构建表,

比如第一个数是3,那么就是 table[3] = 0;  第二个数是5,那么table [5] = 1; 那么构建的table 就是 [ 7, 9, 3, 0, 5, 1, 4, 2, 8, 6]

在输入的时候直接把表就构建好了,然后我们要做的就是怎么利用这个自己构建的表来实现物理存储的改变。

构建了表之后。检验一下,对于我们构造的输入 A [0] = A[ table[0] ] = A[ 7 ]= 0, BINGO! 

1)为什么会有环: 比如给定的数组A:

3 5 7 2 6 4 9 0 8 1

那么我希望找到 0, 把他交换到A[0]的位置: 那么我就从 A [ A[0] ] = A [3] = 2 去找,再找   A[ A[3] ] = A[ 2 ] = 7 , 发现还不是,再找 A[ 7] = 0找到了,那么这样一个找的过程就是构成了一个环,而且每找一次就交换一次;要么我找几次就找到了,要么我找了全部才找到,无非就是环的个数的不同。

2)为什么环是独立的

其实这个很直观,但是用反证法随便证证好了。如果我找到两个环有交叉的,那就代表一个 A[i]  = A[j] , 且 i 不等于 j ,但是cycle sort的一个前提条件是Distinct,所以矛盾。如果有重复值的话,环就会交叉。

3) 这道题的解题思路

0扮演的是一个什么角色呢?0其实代表的就是这个空位。

Input = [3, 5, 7, 2, 6, 4, 9, 0, 8, 1]

table = [ 7, 9, 3, 0, 5, 1, 4, 2, 8, 6]

我们交换 swap(0, 7),那么实际交换的是swap(3, 0 )

再次交换swap (0, 2), 那么实际交换的是swap (7, 3);因为空格位置是 7;


题目:10-排序6 Sort with Swap(0, i)(25 分)

Given any permutation of the numbers {0, 1, 2,..., N1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is allowed to use? For example, to sort {4, 0, 2, 1, 3} we may apply the swap operations in the following way:

Swap(0, 1) => {4, 1, 2, 0, 3}
Swap(0, 3) => {4, 1, 2, 3, 0}
Swap(0, 4) => {0, 1, 2, 3, 4}

Now you are asked to find the minimum number of swaps need to sort the given permutation of the first N nonnegative integers.

Input Specification:

Each input file contains one test case, which gives a positive N (105) followed by a permutation sequence of {0, 1, ..., N1}. All the numbers in a line are separated by a space.

Output Specification:

For each case, simply print in a line the minimum number of swaps need to sort the given permutation.

Sample Input:

10
3 5 7 2 6 4 9 0 8 1

Sample Output:

9

反正我觉得这道题挺烦的,AC代码:

//
//  main.cpp
//  Sort with Swap
//
//  Created by air on 2018/5/14.
//  Copyright © 2018年 air. All rights reserved.
#include <cstdio>
#include <vector>
using namespace std;
void print(vector<int> v, int n);

int main() {
    int n, num, cnt = 0, ans = 0, index = 1;
    scanf("%d", &n);
    vector<int> v(n);
    for(int i = 0; i < n; i++) {
        scanf("%d", &num);
        v[num] = i;
        if(num != i && num != 0) cnt++;
    }
    while(cnt > 0) {
        if(v[0] == 0) {
            while(index < n) {   //如果不用index的话 也可以用for吧,但是用for去扫描一遍会超时 - -
                if(v[index] != index) {
                    swap(v[index], v[0]);
                    ans++;
                    break;
                }
                index++;
            }
        }
        while(v[0] != 0) {
            swap(v[v[0]], v[0]);
            ans++;
            cnt--;
        }

    }
    printf("%d", ans);
    return 0;
}


void print(vector<int> v, int n){
    for(int i = 0; i < n; i++)
        printf("%d ",v[i]);
    printf("\n");
}



猜你喜欢

转载自blog.csdn.net/qq_25175067/article/details/80308833
今日推荐