菜鸟的算法基础

一、交换算法

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),只需修改临时变量法的类型即可,无需改逻辑。
复制代码
相关推荐
老华带你飞8 小时前
社团管理|基于Java社团管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
爪哇部落算法小助手8 小时前
每日两题day65
数据结构·c++·算法
shayudiandian8 小时前
用LangChain打造你自己的智能问答系统
java·数据库·langchain
麒qiqi8 小时前
【数据结构核心篇】树与哈希(Hash)的原理、特性及实战应用
数据结构·算法·哈希算法
ada7_8 小时前
LeetCode(python)——543.二叉树的直径
数据结构·python·算法·leetcode·职场和发展
橘颂TA8 小时前
【剑斩OFFER】算法的暴力美学——颜色分类
数据结构·c++·算法·动态规划
吴秋霖8 小时前
profileData纯算逆向分析
算法·设备指纹·反爬虫技术
sprintzer8 小时前
11.26-12.05力扣栈刷题
算法·leetcode·职场和发展
sin_hielo8 小时前
leetcode 3578
数据结构·算法·leetcode