实现in-place的数据交换


声明:引用请注明出处http://blog.csdn.net/lg1259156776/


经典的排序问题

问题描述

一个数组中包含两个已经排好序的子数组,设计一个in-place(原位操作)算法来对这个数组排序。测试数据为 a[] = 1 4 5 7 8 9  2 3 6 10 11 。

问题分析

排序是一个非常经典的算法设计问题,这个不是难点,难点在于设定的in-place操作,意思是所有的操作都是”就地“操作,不允许进行移动。在我的博文《排序算法一:直接插入排序》中讲到了对于排序算法,时间复杂度在于项目间的比较和移动次数,这里的in-place操作指的就是设定移动次数为0。分析排序算法中为何需要项目间的移动,主要是为了节省内存消耗(空间复杂度),在原有的数组内存空间上进行排序,这样就需要为已经排好序的数据倒腾内存,通常的解决办法是将要倒腾的内存位置上的未排序的数据存在一个临时变量(temp)进行保存,然后其它的数据依次移动。这样的算法额外的空间消耗只有O(1)。题目中的要求是这个临时变量也不能用。实际上是要解决in-place的数据交换操作。

解决方案:in-place数据交换

通过异或操作实现原位数据交换。

#include <iostream>

using namespace std;

void swap(int &x, int &y)
{
x = x ^ y;
y = x ^ y;
x = x ^ y;
} void insertion(int a[], int sz)
{
for(int i=1; i < sz; i++) {
int j = i;
while(j > 0) {
if(a[j-1] > a[j]) swap(a[j-1],a[j]);
j--;
}
}
for(int i = 1; i < sz; i++) cout << a[i] << " ";
} int main()
{
int a[] = { 1, 4, 5, 7, 8, 9, 2, 3, 6, 10, 11 };
int size = sizeof(a)/sizeof(int);
for (int i = 0; i < size; i++) cout << a[i] << " ";
cout << " ==> " << endl;
insertion(a, size);
cout << endl;
return 0;
}

输出为:

1 4 5 7 8 9 2 3 6 10 11   ==>
2 3 4 5 6 7 8 9 10 11

分析原位数据交换

设定X=1001,Y=0111进行原位数据交换操作的验证:

X=X xor Y=1110Y=X xor Y=1001X=X xor Y=0111

从中可以看出X和Y在不借助任何临时变量的存储前提下,in-place的完成了交换。


2015-9-24 艺少

in-place数据交换的更多相关文章

  1. Android:Activity+Fragment及它们之间的数据交换.

    Android:Activity+Fragment及它们之间的数据交换 关于Fragment与Fragment.Activity通信的四种方式 比较好一点的Activity+Fragment及它们之间 ...

  2. Atitit.常见软件 数据 交换格式 标准

    Atitit.常见软件 数据 交换格式 标准 1. 常见的数据格式txt ,doc ,pic,music ,vodio1 2. 通用格式json yaml phpstr1 3. 专用格式1 4. 用户 ...

  3. Js中JSON数据交换使用总结

    Json格式简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是JavaScript原 ...

  4. Java--Exchanger用于进行线程间的数据交换

    package com; import java.util.concurrent.Exchanger; /** * Created by yangyu on 16/11/28. */ /** * Ex ...

  5. 【AS3】Flash与后台数据交换四种方法整理

    随着Flash Player 9的普及,AS3编程也越来越多了,所以这次重新整理AS3下几种与后台数据交换方法.1.URLLoader(URLStream)2.FlashRemoting3.XMLSo ...

  6. JQuery + XML作为前后台数据交换格式实践

    JQuery + xml作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ xml作为一种 ...

  7. JQuery + JSON作为前后台数据交换格式实践

    JQuery + JSON作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ JSON作为 ...

  8. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

  9. java5 Exchanger数据交换

    Java并发API提供了一种允许2个并发任务间相互交换数据的同步应用.更具体的说,Exchanger类允许在2个线程间定义同步点,当2个线程到达这个点,他们相互交换数据类型,使用第一个线程的数据类型变 ...

  10. thread_Exchanger数据交换

    Exchanger 是一个同步辅助类,用于两个并发线程之间在一个同步点进行数据交换.  允许两个线程在某一个点进行数据交换. 可以视作双向的同步队列: 可应用于基因算法.流水线设计等场景 Exchan ...

随机推荐

  1. spring boot 对某个接口进行次数限制,防刷。简易版。demo。

    一般的项目 如果没有做防刷 容易被人爆接口 或者就是说没有做token防刷过滤. 容易被人用正常的token刷接口.有些token非一次性. 用户登录之后生成token会有一个过期时间,但一般没有做频 ...

  2. ROS计算图级

    上一节说到一个 package 可以包含多个可执行文件(节点),可执行文件需要被运行,就要了解ROS的通信架构,也就是计算图级,例: 小萝卜机器人拥有驱动系统,感知系统,控制系统等,要让它从指定位置到 ...

  3. ajax案例_校验用户名

    目录 ajax案例_校验用户名 代码下载 需求 流程 搭建环境 开发代码 1_jsp 1_servlet 1_service.dao 2_servlet 2_jsp 测试后,功能实现,完结撒花 aja ...

  4. spark map函数中使用println无法输出

    问题 // 每个点为hardData中的一个Array val hardData = spark.read.textFile(args(0)).rdd .map(_.split(" &quo ...

  5. linux red hat下安装tomcat的过程

    linux下安装tomcat <-----------1.0----------------->:首先需要先去tomcat官网下载linux版本的tomcat的安装包;  我在官网上下载的 ...

  6. Telegraf+Influxdb+Grafana(Windows下本机简易监控系统搭建)

    1.文件名称 telegraf-1.5.0_windows_amd64.zip influxdb-1.4.2_windows_amd64.zip grafana-4.6.3.windows-x64.z ...

  7. python wmi远程数据获取

  8. linux nand flash常用命令

    使用命令前用cat /proc/mtd 查看一下mtdchar字符设备:或者用ls -l /dev/mtd*#cat /proc/mtddev:    size   erasesize  namemt ...

  9. CV2——学习笔记-图像分类

    1.图像分类 • 2.神经网络原理 • 1.卷积神经网络介绍 • 2.利用caffe搭建深度网络做图像分类 挑战:光照变化+形变.类内变化. 标签.预测函数,泛化能力. 如何提高泛化能力?需要用图像特 ...

  10. PHP获取上周一和上个月

    PHP获取上周一有个坑,如果今天是周一,获取的是上周一.如果今天是周二到周日,获取的是本周一. 根据传递的页码数和每页显示多少条,获取对应的数据: if ($data['type'] == 'day' ...