交换两变量值的几种算法分析

  在码代码的过程中可能会经常涉及到需要交换两变量的值,有时甚至需要大量频繁地交换一系列变量的值,在网上收集了一些算法,附带上自己的一点粗浅分析,且作备忘。

1、通用经典算法

int temp,a,b;
temp=a;
a=b;
b=temp;
  通过引入第三变量temp来达到交换a、b值的目的,容易理解、不会产生歧义并且可移植性强,必要时甚至可以使用寄存器变量register int temp;以达到快速存取的目的,是十分经典的算法,每一个初学者都会认识到的算法,是赋值语句的经典应用。唯一不足就是借助了临时变量,占用了内存,并进行赋值操作的过程中造成了不必要的开销。

  以下几种算法均不需借助临时变量来完成两变量值的交换,每种算法各有利弊。


2、位运算算法

int a,b;
a=a^b;    //1
b=a^b;    //2
a=a^b;    //3
  这个算法的实现借助于关于位运算的几个规律:

1)a^a=0

2)a^(b^c)=(a^b)^c 

3)a^0=a

  假设a、b代表的值分别为p、q

 ab
 pq
p^qq
p^qp^q^q
(p^q)^(p^q^q)p^q^q

 应用规律算出结果便知a=q b=p 达到了交换的目的了。

 这个算法表达式也可以简化为

a^=b^=a^=b;
 这样,我们便可轻松地通过宏定义来实现a、b互换函数swap(a,b):

#define swap(a,b) a^=b^=a^=b;
  这个算法的缺陷在于,当a、b为同一个数,即a、b拥有相同的地址时(而非a==b这种情况),将会使a、b的值置零,在使用这个算法的时候要特别注意,例如如下情况:

#include <stdio.h>
#define swap(a,b) a^=b^=a^=b;


int main()
{
    int a[2]={1,2};
    swap(a[0],a[1]);
    printf("%d %d\n",a[0],a[1]);
    swap(a[0],a[0]);
    printf("%d %d\n",a[0],a[1]);
    return 0;
}
   此时输出的结果为

 2 1

 0 1

   意味着a[1]与a[0]的值正确交换,但是a[0]的值在随后的操作中被置零了,只要对该算法稍作分析便可明白出现这种情况的原因,所以,如果采用这个算法实现,在编程的过程中也无法确切知道swap的两变量是否是同一个变量,使用前先进行判断为好。

3、算术运算算法

int a,b;
a=a+b;
b=a-b;
a=a-b;
  只要稍作分析便不难理解该算法的实现过程,该算法的主要弊端在于,当a+b≥MAX_INT时,将会造成数据溢出,但溢出是相对的,在加的过程后又进行了减运算,将导致最后的结果符合预期,只不过存在不安全因素,该方法同样用的比较普遍。下面通过一个实例来说明:

#include <stdio.h>

int main()
{
    unsigned short a=65534,b=2;  //无符号短整型表示数范围为0~65535
    a=a+b;
    printf("%d %d\n",a,b);
    b=a-b;
    printf("%d %d\n",a,b);
    a=a-b;
    printf("%d %d",a,b);
}
输出分别为:



4、栈运算算法

int exchange(int x,int y)
{
    stack S;
    push(S,x);
    push(S,y);
    x=pop(S);
    y=pop(S);
}
  栈运算的方法不需要解释,没有使用第三个变量但是使用了栈操作并且使用了函数来完成,就复杂性而言得不偿失,并不推荐。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值