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 的每个数字,你需 要输出过程中达到的最左位置下标和最右位置下标的差的绝对值。
★数据输入
第一行为 N,表示排列长度。 第二行为排列 P。 数据保证: 80%的数据,N <= 1000 100%的数据,N <= 100000
★数据输出
输出一行,第 i 个数字表示数字 i 最左与最右位置的差的绝对值。
测试样例
输入:
4
3 2 1 4
输出:2 1 2 0
解题思路:根据题目意思我们可以看出每个数的最左端和最右端的位置的差值的绝对值,而每个数向右移动多少只需要看右边有几个比他更小的数就可以,左端就只需要看最开始的位置和最终的位置的更小的值就可以,然后寻找每个数的后缀更小的数的个数以及对整个数组进行排序就可以通过归并排序的思想实现。
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define MAX_SIZE 100005
using namespace std;
int tmp[MAX_SIZE], num[MAX_SIZE], smaller[MAX_SIZE],loca[MAX_SIZE];
int sum = 0, n;
int min(int a, int b)
{
return a > b ? b : a;
}
void Merge(int l,int r,int mid)
{
int i = l, j = mid + 1, k = l, sum = 0;
while (i <= mid&&j <= r)
{
if (num[i] > num[j])
{
// smaller[num[i]]++;
tmp[k++] = num[j++];
sum++;
}
else
{
smaller[num[i]] += sum;
tmp[k++] = num[i++];
}
}
while (i <= mid)
{
tmp[k++] = num[i];
smaller[num[i]] += sum; i++;
}
while (j <= r)
{
tmp[k++] = num[j++];
}
for (i = l; i <= r; i++)num[i] = tmp[i];
}
void Merge_Sort(int l, int r)
{
if (l >= r)return;
int mid = (l + r) >> 1;
Merge_Sort(l,mid);
Merge_Sort(mid + 1, r);
Merge(l, r, mid);
}
int main()
{
int i, j;
cin >> n;
for (i = 1; i <= n; i++)
{
cin >> num[i]; loca[num[i]] = i;
}
Merge_Sort(1, n);
for (i = 1; i <= n; i++)
{
printf("%d%c", loca[i]+smaller[i]-min(loca[i],i), i != n ? ' ' : '\n');
// printf("%d%c", num[i], i != n ? ' ' : '\n');
}
return 0;
}
解题感想:很久以前就对归并排序不是很清楚,一直没有好好的理清楚,现在趁着复习算法认真的理解研究了一下,用VS断点一步一步领会,同时对二分递归也有一个更好的理解。
同时分享一篇今天看到的挺好的文章,执行力很重要!
bubble_sort(归并排序)的更多相关文章
- 归并排序 & 计数排序 & 基数排序 & 冒泡排序 & 选择排序 ----> 内部排序性能比较
2.3 归并排序 接口定义: int merge(void* data, int esize, int lpos, int dpos, int rpos, int (*compare)(const v ...
- C++/C实现各种排序算法(持续更新)--冒泡排序,选择排序,归并排序
2018 3 17 今日总结一下C++中的排序算法: 1冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是 ...
- 插入排序、冒泡排序、选择排序、希尔排序、高速排序、归并排序、堆排序和LST基数排序——C++实现
首先是算法实现文件Sort.h.代码例如以下: <pre name="code" class="java">/* * 实现了八个经常使用的排序算法: ...
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- Python实现八大排序(基数排序、归并排序、堆排序、简单选择排序、直接插入排序、希尔排序、快速排序、冒泡排序)
目录 八大排序 基数排序 归并排序 堆排序 简单选择排序 直接插入排序 希尔排序 快速排序 冒泡排序 时间测试 八大排序 大概了解了一下八大排序,发现排序方法的难易程度相差很多,相应的,他们计算同一列 ...
- 算法与数据结构(十五) 归并排序(Swift 3.0版)
上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...
- [算法]——归并排序(Merge Sort)
归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...
- 归并排序的java实现
归并排序的优点不说了. 做归并排序之前,我先试着将两个有序数组进行排序,合并成一个有序数组. 思路:定义好两个有序数组,理解的时候我先思考了数组只有一个数组的排序,然后是两个元素的数组的排序,思路就有 ...
- JavaScript算法(归并排序与快速排序)
归并排序与快速排序这两个算法放在一起,也是因为时间复杂度都是对数级别的. 目前看过的资料,归并排序看<学习JavaScript数据结构与算法>介绍的归并排序吧,快速排序直接看百度百科,讲的 ...
随机推荐
- Wifi NAT Driver
最近遇点奇葩问题,最开始以为被种马了经检测发现不是,分享下以后大家出现类似也好解决:同时列出尝试过程以便大家以后自行排除自己网络问题: 症状: 网络连接右下角图标显示为网卡无线网卡和有线均禁用状态,查 ...
- JavaWeb基础—Tomcat
JavaWeb服务器:可以运行以及发布JavaWeb应用的JavaWeb容器,开发项目必须放在该容器中才可以被浏览器访问.(只能等待请求,然后做出响应) 静态资源(HTML):数据始终不变 动态资源( ...
- 2017-2018-1 20155226 《信息安全系统设计基础》课下实践——实现mypwd
2017-2018-1 20155226 <信息安全系统设计基础>课下实践--实现mypwd 1 学习pwd命令 输入pwd命令 发现他是给出当前文件夹的绝对路径. 于是 man 1 pw ...
- 北京Uber优步司机奖励政策(4月25日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- python基础学习1-类属性访问
#!/usr/bin/env python # -*- coding:utf-8 -*- #====> __setattr__ 重写 设置类对象属性值时候调用的魔法方法 __getattr__( ...
- CF1017G The Tree 树链剖分
CF1017G The Tree LG传送门 树链剖分好题. 乍一看还以为是道沙比题,然后发现修改操作有点不一样. 但是如果你对基本操作还不太熟练,可以看看我的树链剖分总结 有三个操作: 从一个点往下 ...
- bzoj 3232: 圈地游戏
bzoj 3232: 圈地游戏 01分数规划,就是你要最大化\(\frac{\sum A}{\sum B}\),就二分这个值,\(\frac{\sum A}{\sum B} \geq mid\) \( ...
- IDEA中java文件的左下角有个像乐符一样的J符号
- Jenkins + Gitlab + Ansible--playbook 代码上线流程(文末有免费视频)
jenkins 构建是支持 git 选择分支 安装 Git Parameter 插件在系统管理中的插件管理 然后点击选插件,在右上角输入 Git Parameter,找到 Git Paramete ...
- c语言数字图像处理(六):二维离散傅里叶变换
基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...