交换最小次数 和一些排序方式

问题:洛谷P8637 交换瓶子

有 N个瓶子,编号 1∼N,放在架子上。

比如有 5 个瓶子:

2,1,3,5,4

要求每次拿起 2 个瓶子,交换它们的位置。

经过若干次后,使得瓶子的序号为:

1,2,3,4,5

对于这么简单的情况,显然,至少需要交换 2 次就可以复位。

如果瓶子更多呢?你可以通过编程来解决。

输入格式
第一行:一个正整数 N(N<10000),表示瓶子的数目。

第二行:N 个正整数,用空格分开,表示瓶子目前的排列情况。

输出格式
输出数据为一行一个正整数,表示至少交换多少次,才能完成排序。

 


 

思路:

不在规定位置上的用圈排序把它放到它应该呆的位置上。

 圈排序只查看一下有多少需要排序,不进行排序。

复制代码
#include<bits/stdc++.h>
using namespace std;
int a[10010],s,ans,n,k;
void pencil(int l,int m)//递归
{
    if(s==k) 
    {
        a[l]=0;
        return ;
    }
    s=a[m];
    ans++;
    a[l]=0;
    return pencil(m,s);
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        if(i==a[i]||a[i]==0)
        continue;
        s=0;
        k=i;
        pencil(i,a[i]);
        a[i]=0;
        
    }
    cout<<ans;
    return 0;
}
复制代码

 


 拓展

解决只能交换相邻两数的情况

逆序数

         首先定义一个标准次序(例如对于n个不同的自然数,可规定从小到大为标准次序)。于是在这n个元素的任一排列中,当某两个元素的先后次序与标准次序不同时,就说有一个逆序。

        例如在一个排列中,如果一对数的前后与大小顺序正好相反(即:前面的数大于后面的数),那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。根据逆序数

的奇偶可将排列分为奇排列和偶排列。

         比如: 7 5 1 6 3            按从小到大为标准次序,逆序为7,5   7,1   7,6   7,3   5,1   5,3   6,3        逆序数为7

    7,5  7,1  7,6  7,3  5 1 6 3 7

    6,3  5,1  1 5 3 6 7

    5,3  1 3 5 6 7  一共交换七次。

算法:归并算法


 解决交换任意两个数,求最少交换次数

圈排序:(Cycle Sort)

 不在排序后位置上的需要交换位置。


 

快速排序:O(nlog2n)

基本思想:  任取一个元素(如第一个)为中心,比它小的放在前面,大的放在后面

  结果会被这个元素分成两部分,两部分再取第一个元素为中心,小的放在前面,大的放在后面。(递归,分而治之)


 

基数排序:适合多关键字排序 

n:往桶里扔的时候要扔多少元素

 


 计数排序:

          7 2 3 6 4

比它小的数的个数  4 0 1 3 2,即为每个数在数组中的位置。  

           

posted @   椿の花少年  阅读(266)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示