菜鸟的算法基础

一、交换算法

C语言交换两个数的3种实现方法(附完整示例)

交换两个数是C语言基础操作,以下提供3种核心实现方式,涵盖「通用无风险」「无临时变量」等场景,附原理、代码和优缺点分析。

方法1:临时变量法(最推荐,通用无风险)

核心思路

定义一个临时变量作为"中转站",先保存其中一个数的值,再完成交换,是最基础、通用且无副作用的方法,适用于所有数据类型(int/float/double等)。

代码示例

c 复制代码
#include <stdio.h>

// 交换整数(通用版,可适配其他类型)
void swap(int *a, int *b) {
    int temp; // 临时变量
    temp = *a; // 保存a的值到临时变量
    *a = *b;   // 把b的值赋给a
    *b = temp; // 把临时变量(原a值)赋给b
}

// 测试交换浮点数(仅需修改类型)
void swap_float(float *a, float *b) {
    float temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    // 测试交换整数
    int x = 10, y = 20;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y); // 传地址(指针),才能修改原变量
    printf("交换后:x=%d, y=%d\n\n", x, y);

    // 测试交换浮点数
    float m = 3.14, n = 6.28;
    printf("交换前:m=%.2f, n=%.2f\n", m, n);
    swap_float(&m, &n);
    printf("交换后:m=%.2f, n=%.2f\n", m, n);

    return 0;
}

优点&缺点

  • ✅ 优点:逻辑简单、无溢出风险、适配所有数据类型(整数/浮点/字符等);
  • ❌ 缺点:需要额外占用1个临时变量的内存(可忽略,几乎无影响)。

方法2:算术运算法(不用临时变量,仅适用于数值类型)

核心思路

利用「加减运算」抵消值的差异,无需临时变量,但仅适用于整数/浮点型,且两个大数相加可能触发溢出(超出数据类型取值范围)。

代码示例

c 复制代码
#include <stdio.h>

void swap(int *a, int *b) {
    *a = *a + *b; // a = 原a + 原b
    *b = *a - *b; // b = (原a+原b) - 原b = 原a
    *a = *a - *b; // a = (原a+原b) - 原a = 原b
}

int main() {
    int x = 5, y = 8;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    return 0;
}

优点&缺点

  • ✅ 优点:无需临时变量,代码简洁;
  • ❌ 缺点:
    1. 仅适用于数值类型(无法交换字符/字符串等);
    2. 整数相加可能溢出(如a=2^30b=2^30,相加后超出int范围);
    3. ab指向同一地址(swap(&x, &x)),结果会变为0(逻辑错误)。

方法3:位运算法(异或,仅适用于整数)

核心思路

利用异或运算(^) 的特性:

  • 一个数异或自身等于0(a^a=0);
  • 一个数异或0等于自身(a^0=a);
  • 异或满足交换律和结合律(a^b^c = a^(b^c))。
    仅适用于整数类型(char/int/long等),无溢出风险。

代码示例

c 复制代码
#include <stdio.h>

void swap(int *a, int *b) {
    if (a == b) return; // 避免同一地址异或后变为0
    *a = *a ^ *b; // 步骤1:a = 原a ^ 原b
    *b = *a ^ *b; // 步骤2:b = (原a^原b) ^ 原b = 原a
    *a = *a ^ *b; // 步骤3:a = (原a^原b) ^ 原a = 原b
}

int main() {
    int x = 100, y = 200;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    return 0;
}

优点&缺点

  • ✅ 优点:无需临时变量、无溢出风险、仅操作二进制位,效率高;
  • ❌ 缺点:
    1. 仅适用于整数类型(无法交换浮点/字符);
    2. 可读性差(需理解异或特性);
    3. ab指向同一地址,结果会变为0(需加判断规避)。

关键注意事项

  1. 传参方式:上述代码均用「指针传参」,因为C语言默认是"值传递",直接传变量会复制一份值,无法修改原变量;
  2. 选型建议
    • 日常开发/通用场景:优先用「临时变量法」(无坑、易维护);
    • 嵌入式/内存极度受限场景:用「位运算法」(仅整数);
    • 避免用「算术运算法」(溢出风险高);
  3. 扩展适配 :若需交换其他类型(如double/char),只需修改临时变量法的类型即可,无需改逻辑。
复制代码
相关推荐
Jerry23 分钟前
LeetCode 28. 找出字符串中第一个匹配项的下标
算法
Jerry2 小时前
LeetCode 459. 重复的子字符串
算法
闲猫5 小时前
Spring AI 对接Deepseek ChatModel 聊天对话
java·前端·spring
海石5 小时前
1500分的题目,确实有实力,不过还是我略胜一筹
算法·leetcode
海石5 小时前
【记忆化搜索】条条大路通AC,走好适合你的那一条,走到后再考虑走得快
算法·leetcode
自信的未来7 小时前
JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
java·前端·json
Brookty7 小时前
【JavaEE】线程安全(一).4:写块串行保安全、CAS
java·开发语言·java-ee·多线程·线程安全
Jerry7 小时前
LeetCode 151. 反转字符串中的单词
算法
怕孤单的草丛7 小时前
缓存管理面临的主要问题
java·数据库·缓存