★实验任务

给定一个 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 的每个数字,你需 要输出过程中达到的最左位置下标和最右位置下标的差的绝对值。

★数据输入

第一行为 N,表示排列长度。
第二行为排列 P。
数据保证:
80%的数据,N <= 1000
100%的数据,N <= 100000

★数据输出

输出一行,第 i 个数字表示数字 i 最左与最右位置的差的绝对值。

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

★注释

样例冒泡排序过程:
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

思路

不难发现,对于一个数i,其运动轨迹是先向右移再向左移,原数组i右面有几个比他小的就右移多少格最左端由i原来的位置和最后的位置最小值决定。

那么我们的主要目的就是求一个数后面有几个数比它小

1.最普通的想法就是:每遇到一个数往后找它后面有几个数比它小。这个做法的时间复杂度是n*n,只能适用于规模比较小的数据。

2.归并的想法:建立数组p,p[i]表示数字i后有几个数比它小。在归并的两段序列合并的时候,先令一个计数变量sum=0,扫描左右两段left[],和right[]数组合并时,如果左面的数left[i]比右面的数right[i]大,则p[left[i]]加上这个sum,弹出right[i];如果左面的数left[i]比右面的数right[i]小,则

sum++,弹出left[i]。这样做的原因是左右连个数组已经是有序排列,如果left[i]后面有n个数比它小,则left[i+1]后面也一定至少有n个数比它小。

Code


#include<iostream>
#include<string.h>
using namespace std;
int p[100001]={0},Left[100001]={0},Right[100001]={0};
void merge(int *arr,int l,int mid,int r)
{
int i,j,k;
for(i = l;i <= mid;i++)
{
Left[i] = arr[i];
}
for(j = mid+1;j <= r;j++)
{
Right[j] = arr[j];
}
i=l,j=mid+1,k=l;
int sum=0;
while((i<=mid)&&(j<=r))
{
if(Left[i]>Right[j])
{
sum++;
arr[k++]=Right[j++];
}
else
{
p[Left[i]]+=sum;
arr[k++]=Left[i++];
}
}
while(i <= mid)
{
arr[k++] = Left[i++];
p[Left[i-1]] += sum;
}
while(j <= r)
{
arr[k++] = Right[j++];
}
}
void mergesort(int *arr,int l,int r)
{
int mid=(l+r)/2;
if(r<=l)return;
mergesort(arr,l,mid);
mergesort(arr,mid+1,r);
merge(arr,l,mid,r);
}
int min(int x,int y)
{
if(x>y)return y;
else return x;
}
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
int n,i;
int a[100001],b[100001];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[a[i]]=i;
}
mergesort(a,1,n);
// for(i=1;i<=n;i++)
// {
// printf("%d ",p[i]);
// }
// printf("\n");
for(i=1;i<=n;i++)
{
printf("%d ",b[i]+p[i]-min(b[i],i));
}
return 0;
}

算法与数据结构5.2 Bubble Sort的更多相关文章

  1. c++算法联系,冒泡排序,bubble sort,插入排序,insert sort,

    #include <iostream.h> #define  MAX 100 void dispaly(int a[],int n) {     for(int i=0;i<n;i+ ...

  2. 算法之经典排序-冒泡排序(bubble sort)

    冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成. 这个算法的名字由来是因为越大的元 ...

  3. 八大排序算法之五--交换排序—冒泡排序(Bubble Sort)

    基本思想: 在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将 ...

  4. 算法与数据结构5.1 Just Sort

    ★实验任务 给定两个序列 a b,序列 a 原先是一个单调递增的正数序列,但是由于某些 原因,使得序列乱序了,并且一些数丢失了(用 0 表示).经过数据恢复后,找 到了正数序列 b ,且序列 a 中 ...

  5. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  6. [算法] 冒泡排序 Bubble Sort

    冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...

  7. java排序算法之冒泡排序(Bubble Sort)

    java排序算法之冒泡排序(Bubble Sort) 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数 ...

  8. 排序算法--冒泡排序(Bubble Sort)_C#程序实现

    排序算法--冒泡排序(Bubble Sort)_C#程序实现 排序(Sort)是计算机程序设计中的一种重要操作,也是日常生活中经常遇到的问题.例如,字典中的单词是以字母的顺序排列,否则,使用起来非常困 ...

  9. 【排序算法】冒泡排序(Bubble Sort)

    0. 说明 参考 维基百科中的冒泡排序 冒泡排序 (Bubble Sort) 是与插入排序拥有相等的执行时间,但是两种算法在需要的交换次数却很大地不同. 在最坏的情况,冒泡排序需要 O(n2)  次交 ...

随机推荐

  1. 异常笔记:Hadoop异常 namenode.NameNode: Encountered exception during format

    00:53:47,977 WARN namenode.NameNode: Encountered exception during format: java.io.IOException: Canno ...

  2. 第3章 jQuery中的DOM操作

    parent() .parents().closest() 区别示例: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitiona ...

  3. JSON API免费接口 各种提供JSON格式数据返回服务网站的API接口

    这里为大家搜集了一些能够返回JSON格式的服务接口.部分需要用JSONP调用. 电商接口 京东获取单个商品价格接口: http://p.3.cn/prices/mgets?skuIds=J_商品ID& ...

  4. c语言中:strlen和sizeof的区别和它们分别交换各自作用领域(\0问题)时的细微差别!!!

    本人c语言初学菜鸟一枚,今天通过敲了一段简单代码,发现strlen和sizeof之间的一些关系,总结如下: 用strlen计算数组长度要考虑进去\0 用sizeof计算字符串长度也要考虑进去\0 而s ...

  5. Linux大文件split分割以及cat合并

    文件大小分割文件时,需要以-C参数指定分割后的文件大小: $ split -C 100M large_file.txt stxt   如上所示,我们将大文件large_file.txt按100M大小进 ...

  6. javascript之input字符串不为空

    今天我们来讲如何判断这个java中字符串输入是否为空 ------------------------当只有一个input的时候,我们来进行个判断这个值是否为空-------------------- ...

  7. GDAL2.1.1库在Ubuntu14.04下编译时遇到的问题处理方法

    不用作任何调整,直接在Linux下编译GDAL2.1.1源码的步骤是: $ ./configure $ make $ make install 非常简单,这样也能正常生成gdal动态库.静态库,如果想 ...

  8. `Facebook.Unity.Settings' has already been imported error solution

    after import facebook sdk to unity, i get the '`Facebook.Unity.Settings' has already been imported' ...

  9. ASP.NET数据库连接

    启动Visual Studio,新建一个web工程 点开工程目录下web.config文件, 找到节点,新增数据库配置 aspx界面新建一个button和一个文本框用于测试数据库连接, 其中butto ...

  10. ElasticSearch搜索引擎在JavaWeb项目中的应用

    近几篇ElasticSearch系列: 1.阿里云服务器Linux系统安装配置ElasticSearch搜索引擎 2.Linux系统中ElasticSearch搜索引擎安装配置Head插件 3.Ela ...