in-place数据交换

实现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 艺少

版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/lg1259156776/。

时间: 2024-10-13 22:46:33

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

java中的线程协调与线程间的数据交换

Java中提供多种方式协调线程的工作. CountDownLatch:当多个也就是具体的数量等于CountDownLatch初始化参数的时候.线程达到了预期状态或者完成了预期工作时触发事件,其他线程可以等待这个事件来触发自己的后续工作.等待的线程是多个.达到了预期状态的线程会调用CountDownLatch的countDown方法.等待的线程会调用CountDownLatch的await方法. import java.util.concurrent.CountDownLatch; import

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

JQuery + xml作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ xml作为一种轻量数据格式,被浏览器js引擎普遍支持,同json格式,但是没有json那么精简. 使用AJAX+xml数据格式来实现动态页面,有以下好处: 1. 松耦合, 页面HTML和数据彻底分离, 即表示层 和 数据层分开, 有利前台样式定制. 不同于以往后台脚本嵌套HTML标签,并输出数据到标签的合适位置,

iOS 中 XML 数据交换格式

     XML 是一种自描述的数据交换格式,但是 XML 的数据交换格式并没有 JSON 来的轻便,但是无可否认的是,XML 的应用范围也是非常广泛的,比如在 ROS(一个开源机器人操作系统)中利用 XML 来描述包的依赖关系等,当然还有很多了.      对于 XML 文档操作包括了"读"与"写",读入 XML 文档并分析的过程称为"解析" XML 文档,"解析" XML 文档在实际开发中是占很大比重的.      读写

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

本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是CountDownLatch? 倒计时计数器,调用CountDownLatch对象的CountDown()方法就将计数器减一,当计数到达0时,则所有等待者或者全部等待者开始执行. 2.如何用? new CountDownLatch(1); 直接new,其构造函数必须传一个int类型的参数,参数的意思是: c

Disruptor——一种可替代有界队列完成并发线程间数据交换的高性能解决方案

本文翻译自LMAX关于Disruptor的论文,同时加上一些自己的理解和标注.Disruptor是一个高效的线程间交换数据的基础组件,它使用栅栏(barrier)+序号(Sequencing)机制协调生产者与消费者,从而避免使用锁和CAS,同时还组合使用预分配内存机制.缓存行机制(cache line).批处理效应(batch effect)来达到高吞吐量和低时延的目标.目前Disruptor版本已经迭代至3.0,本论文是基于Disruptor1.0写就,在新版本中,相对与1.0版本,其核心设计

第三次作业-前端与后台数据交换问题

问题:JS前端取得并解析后台服务器返回的JSON数据方法有哪些? 前一段时间,我在做一个有关美食的Web App,很多商家的店铺信息以及一些用户评论信息等内容需要从后台来获取,如果仅仅只是静态布局的话就太过于死板,但是在进行前端与后端的数据交换时遇到不少问题,如题目JS前端取得并解析后台服务器返回的JSON数据的方法就是问题之一. 在解决这个问题之前,首先需要了解JavaScript eval()函数,eval(string)函数可计算某个字符串,并执行其中JavaScript代码. JS前端取

iOS 中 JSON 数据交换格式

     JSON (JavaScript Object Notation)是一种轻量级的数据交换格式.JSON 的具体教程,可以参见 JSON 中国:http://www.json.org.cn/index.htm ,当然还有 JSON 在线校验格式化工具:http://www.bejson.com/ ,希望深入学习 JSON 可以参考其他教程.JSON 的轻量级是相对于 XML 文档结构而言的,描述项目字符少,所以描述相同的数据所需的字符个数要少,当然传输的速度就会提高而流量也会减少.  

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

JQuery + JSON作为前后台数据交换 JQuery提供良好的异步加载接口AJAX,可以局部更新页面数据, http://api.jquery.com/category/ajax/ JSON作为一种轻量数据格式,被浏览器js引擎普遍支持,同xml格式. 使用AJAX+JSON数据格式来实现动态页面,有以下好处: 1. 松耦合, 页面HTML和数据彻底分离, 即表示层 和 数据层分开, 有利前台样式定制. 不同于以往后台脚本嵌套HTML标签,并输出数据到标签的合适位置, 来实现动态页面,表示

MFC拆分窗口及它们之间的数据交换[转]

源代码:http://download.csdn.net/detail/nuptboyzhb/4221531 CSplitterWnd类 CSplitterWnd类提供一个分隔器窗口的功能,分隔器窗口是一个包含有多个窗格的窗口.窗格通常是应用程序特定的由CView派生的对象,但它也可以是具有适当子窗口ID的任何CWnd对象. 一个CSplitterWnd对象通常被嵌入CFrameWnd或CMDIChildWnd父对象.你应按如下步骤创建一个CSplitterWnd对象 1.在父框架中嵌入一个CS

配置VirtualBox虚拟机实现Ubuntu与Windows系统间数据交换即Putty的访问

一.直接修改Ubuntu IP系统配置文件 Ubuntu IP的网络配置文件是:/etc/network/interfaces打开后里面可设置DHCP或手动设置静态Static IP.前面auto eth0,让网卡开机自动挂载,以下操作针对有线网络在Ubuntu中实现两个网卡.               1.以DHCP方式配置网卡(推荐) (1)打开要编辑的文件interfaces 它的的目录是/etc/network/interfaces