小朋友学经典算法(13):两数交换

作者: 海天一树X | 来源:发表于2018-08-19 16:04 被阅读46次

在学C语言的时候,学过两数交换:《小朋友学C语言(25):两数交换》
https://www.jianshu.com/p/64bc70f0abfe

在学C++的时候,也学了两数交换:《小朋友学C++(14):两数交换》
https://www.jianshu.com/p/9a071870e0a0

这里咱们要考虑的是,两个数相等的交换情况。

#include <iostream>
#include <algorithm>
using namespace std;

// 两个参数是指针(指向地址的引用)
void myswap(int *x, int *y)
{
    *x ^= *y;
    *y ^= *x;
    *x ^= *y;
}

// 两个参数是引用,在这里&代表引用,不代表地址
void myswap2(int &x, int &y)
{
    x ^= y;
    y ^= x;
    x ^= y;
}

int main()
{
    cout << "**********交换不同的值**********" << endl;
    int a = 1, b = 2;
    myswap(&a, &b); // 因为myswap的参数是指针,所以必须传地址
    cout << a << ' ' << b << endl;

    int a2 = 3, b2 = 4;
    myswap2(a2, b2);
    cout << a2 << ' ' << b2 << endl;

    cout << "**********交换相同的值**********" << endl;
    int a3 = 5, b3 = 5;
    myswap(&a3, &b3); // 因为myswap的参数是指针,所以必须传地址
    cout << a3 << ' ' << b3 << endl;

    int a4 = 6, b4 = 6;
    myswap2(a4, b4);
    cout << a4 << ' ' << b4 << endl;

    int c[1];
    c[0] = 7;
    myswap(&c[0], &c[0]);
    cout << c[0] << ' ' << c[0] << endl;

    int d[1];
    d[0] = 8;
    myswap2(d[0], d[0]);
    cout <<d[0] << ' ' << d[0] << endl;

    int e[1];
    e[0] = 9;
    swap(e[0], e[0]);
    cout <<e[0] << ' ' << e[0] << endl;

    return 0;
}

运行结果:

**********交换不同的值**********
2 1
4 3
**********交换相同的值**********
5 5
6 6
0 0
0 0
9 9

结果显示,前两组数值不同的两个数,能交换成功。后五组相同的值,交换成功的有3组。不成功的有两组,并且值都变成了0。
这是什么原因呢?
观察最后三对的数,都是数组里的同一元素交换。myswap和myswap2函数是咱们自己定义的,swap函数是由<algorithm>提供的。可见自己写的两个函数,一定存在bug。

仔细观察,发现a3 = 5, b3 = 5,这是两个不同的变量(在内存里的地址不同),而myswap2(d[0], d[0]),这是对同一个地址里的数交换。
d0 = 8时,
a = a ^ b = 8 ^ 8 = 0,因为a和b都指向d0,所以此时b = a = 0。
b = b ^ a = 0 ^ 0 = 0,
a = a ^ b = 0 ^ 0 = 0,
所以最终得到的是0 0,而不是8 8。
对于myswap(&c[0], &c[0]),与myswap2(d[0], d[0])的道理是一样的。

改进:如果值一样,那就不用交换了:

#include <iostream>
#include <algorithm>
using namespace std;

// 两个参数是指针(指向地址的引用)
void myswap(int *x, int *y)
{
    if(x != y)
    {
        *x ^= *y;
        *y ^= *x;
        *x ^= *y;
    }
}

// 两个参数是引用,在这里&代表引用,不代表地址
void myswap2(int &x, int &y)
{
    if(x != y)
    {
        x ^= y;
        y ^= x;
        x ^= y;
    }
}

int main()
{
    cout << "**********交换不同的值**********" << endl;
    int a = 1, b = 2;
    myswap(&a, &b); // 因为myswap的参数是指针,所以必须传地址
    cout << a << ' ' << b << endl;

    int a2 = 3, b2 = 4;
    myswap2(a2, b2);
    cout << a2 << ' ' << b2 << endl;

    cout << "**********交换相同的值**********" << endl;
    int a3 = 5, b3 = 5;
    myswap(&a3, &b3); // 因为myswap的参数是指针,所以必须传地址
    cout << a3 << ' ' << b3 << endl;

    int a4 = 6, b4 = 6;
    myswap2(a4, b4);
    cout << a4 << ' ' << b4 << endl;

    int c[1];
    c[0] = 7;
    myswap(&c[0], &c[0]);
    cout << c[0] << ' ' << c[0] << endl;

    int d[1];
    d[0] = 8;
    myswap2(d[0], d[0]);
    cout <<d[0] << ' ' << d[0] << endl;

    int e[1];
    e[0] = 9;
    swap(e[0], e[0]);
    cout <<e[0] << ' ' << e[0] << endl;

    return 0;
}

运行结果:

**********交换不同的值**********
2 1
4 3
**********交换相同的值**********
5 5
6 6
7 7
8 8
9 9

现在结果对了。在此,咱们可以进一步推断<algorithm>中的swap函数的实现方式:
(1)参数是用引用而不是用指针,因为调用方式 是swap(e[0], e[0])而不是swap(&e[0], &e[0])
(2)swap内部用if作了判断。

加入少儿信息学奥赛QQ群请扫左侧二维码,关注微信公众号请扫右侧二维码


QQ群和公众号.png

相关文章

  • 小朋友学经典算法(13):两数交换

    在学C语言的时候,学过两数交换:《小朋友学C语言(25):两数交换》https://www.jianshu.com...

  • 小朋友学C++(14):两数交换

    之前学C语言的时候,咱们直接在main函数中使用“异或”位运算符,很容易实现了两数交换。本节课将在此基础上,把交换...

  • 经典算法 — 两数之和

    经典算法 — 两数之和 题目描述 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目...

  • 不使用中间变量交换两数

    交换两个数的值是比较基础也比较常用的算法,比如在冒泡排序法中,从第一数开始比较,如后一个数比其小则交换两数的值。 ...

  • 10. 密码学专题 - 密钥交换算法

    密码学专题 - 密钥交换算法 10. 密钥交换算法 10.1 Diffie-Hellman 算法 Diffie-H...

  • 学习java不可不知的几种算法

    1、冒泡排序算法:编程语言算法中比较经典的算法。每个程序员都必须了解和会运用的。 通过多次比较(相邻两个数)和交换...

  • 异或交换算法中的小坑

    突然想起来挺久前的一件事,因为太琐碎就不放到「深夜学算法」系列里了。 「交换两数」大概是编程入门者紧接着Hello...

  • 选择法排序

    可以在找出余下的所有数中的最大值后再与第i+1个数交换位置,这样每一轮比较中最多只有一次两数交换操作,整个算法最多...

  • 冒泡排序

    算法思想: 每次比较相邻的两个元素,如果顺序错误就交换它们的位置 算法原理: 每趟只能将一个数归位,如果n个数进行...

  • iOS备忘:常用排序算法还记得多少...

    冒泡排序 算法思想 通过与相邻元素的比较和交换,把小的数交换到最前面。 选择排序 算法思想 每一趟从前往后查找出值...

网友评论

    本文标题:小朋友学经典算法(13):两数交换

    本文链接:https://www.haomeiwen.com/subject/swmciftx.html