表排序——案例7-1.5 与零交换 (25分)

将 { 0, 1, 2, …, N-1 } 的任意一个排列进行排序并不困难,这里加一点难度,要求你只能通过一系列的 Swap(0, *) —— 即将一个数字与 0 交换 —— 的操作,将初始序列增序排列。例如对于初始序列 { 4, 0, 2, 1, 3 },我们可以通过下列操作完成排序:

Swap(0, 1) ⟹ { 4, 1, 2, 0, 3 }
Swap(0, 3) ⟹ { 4, 1, 2, 3, 0 }
Swap(0, 4) ⟹ { 0, 1, 2, 3, 4 }
本题要求你找出将前 N 个非负整数的给定排列进行增序排序所需要的最少的与 0 交换的次数。

输入格式:
输入在第一行给出正整数 N (≤10
​5
​​ );随后一行给出{ 0, 1, 2, …, N-1 } 的一个排列。数字间以空格分隔。

输出格式:
在一行中输出将给定序列进行增序排序所需要的最少的与 0 交换的次数。

输入样例:
10
3 5 7 2 6 4 9 0 8 1

输出样例:
9

改不出来了
在这里插入图片描述

//利用表排序来达到
//表排序中的独立环分为三类:
/*
 第一种:只有一个元素,不需要交换;
 第二种,环里有n1个元素,包括0,需要n1-1次交换;
 第三种:第i个环里有ni个元素,不包括0:先把0换到环里,再进行(ni+1)-1次交换——一共是ni+1次交换;
 如果N个元素的序列中包含S个单元环,K个多元环,则交换的次数为N-S+K-2次
 */

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAX 100001
void dfs(int x);
int A[MAX];
int T[MAX];
int n;
int cnt=0;
int fll=0;
int main(){
    cin>>n;
    int s=0;
    for(int i=0;i<n;i++){
        scanf("%d",&A[i]);
        T[A[i]]=i;          //元素i在A[T[i]]中存放
        if(A[i]==i){s++;}   //独立的环个数
    }
    for(int i=0;i<n;i++){
        if(T[i]!=i){
            //printf("T[%d]=%d  ",i,T[i]);
            fll=A[i];
            cnt++;      //cnt个多元环
            dfs(i);
        }
    }
    int num=n-s+cnt-2;
    cout<<num<<endl;
}

void dfs(int x){
    //printf("x=%d   ",x);
    if(T[x]!=x){
        int tmp=T[x];
        A[x]=A[T[x]];
        if(T[T[x]]==x){
            A[x]=fll;
        }
        T[x]=x;
        dfs(tmp);
        }
    else return ;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值