C 语言 数组删除指定元素(快慢指针法)

适用场景:在原数组上原地删除所有等于目标值的元素,不额外开辟新数组,时间复杂度 O (n),空间复杂度 O (1)。

核心原理:快慢双指针

  • 快指针 i :负责从头到尾遍历数组的每一个元素,逐个检查。for循环每次i++,一定会向后移动。

  • 慢指针 j :用来标记存放保留元素的位置 。只有当遍历到的元素不需要删除时,j才向后移动。

    数组: [10] [20] [40] [30] [50]
    i: →i →i →i →i →i
    j: →j →j →j j →j

目标:删除数组中所有值等于30的元素。

右侧最终保留的有效数据: 10 20 40 50

逐步骤推演

原始数组:buf = {10, 20, 40, 30, 50},初始状态 i=0,j=0

  1. i=0,buf[i]=10,不等于 30。执行buf[j++] = buf[i],buf[0]=10,j=1
  2. i=1,buf[i]=20,不等于 30。执行buf[j++] = buf[i],buf[1]=20,j=2
  3. i=2,buf[i]=40,不等于 30。执行buf[j++] = buf[i],buf[2]=40,j=3
  4. i=3,buf[i]=30,等于待删除元素。不执行赋值,j 保持为 3,原地不动
  5. i=4,buf[i]=50,不等于 30。执行buf[j++] = buf[i],buf[3]=50,j=4

循环结束。 j=4,代表删除完成之后,数组有效长度为 4。数组前j个元素就是结果:{10,20,40,50}。

重点:数组后面残留的旧数据没有被擦除,我们后续只读取数组前j项即可。

复制代码
#include <stdio.h>
#define MAX 5

int main(void)
{
    int buf[MAX] = {10,20,40,30,50};
    int i,j = 0;

    //快慢指针遍历数组
    for(i = 0; i < MAX; i++)
    {
        //当前元素不是要删除的值,则保留
        if(buf[i] != 30)
        {
            buf[j++] = buf[i];
        }
    }

    //打印删除后的有效数组,j为新数组长度
    printf("删除30之后的数组:");
    for(i = 0; i < j; i++)
    {
        printf("%d ", buf[i]);
    }
    printf("\n");
    return 0;
}

原理示意图

相关推荐
凤凰院凶涛QAQ1 小时前
《Java版数据结构 & 集合类剖析》Map & Set & 反射:“从哈希碰撞到红黑树转换,反射帮你扒开 HashMap 的桶数组看个究竟”
java·数据结构·算法
H.莓飛1 小时前
【数据结构】排序_OJ题(一):计数、桶与排序后的处理
java·开发语言·数据结构
w_zero_one3 小时前
算法--模拟
java·数据结构·算法
秋天的怀念_David4 小时前
算法一千零一夜 · 第十三夜 幻方,武侠世界里的数学迷宫
java·程序人生·算法
·present·4 小时前
CSAPP(lecture 4_01)
c语言·c++
秋天的怀念_David4 小时前
算法一千零一夜 · 第十四夜 幻方与奇妙的二进制
java·程序人生·算法
薛定e的猫咪4 小时前
(ICLR 2020)MAML 靠的不是快速学习,而是特征复用
人工智能·深度学习·学习·算法·机器学习
薛定e的猫咪5 小时前
(ICLR 2026)DF-META:面向 FJSP 的无导数元学习实例自适应调度
人工智能·深度学习·学习·算法·机器学习
小羊没烦恼!6 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
wanderist.6 小时前
202609CSP认证P3
算法