零基础入门C语言之C语言实现数据结构之顺序表经典算法

在阅读本篇文章之前,建议读者优先阅读专栏内前面的文章。

目录

前言

一、经典算法OJ题:移除元素

二、经典算法OJ题:合并两个有序数组

三、关于顺序表的问题和思考

总结


前言

本篇文章借由力扣中的两道经典题目来介绍顺序表中的经典算法。


一、经典算法OJ题:移除元素

我给出这道题的测试链接:

27. 移除元素 - 力扣(LeetCode)

题目描述如下:

其实这道题的思路很简单,我们可以直接创建一个新数组,然后遍历原数组,如果原数组中的数据和我们要求的数据不相等,那就把它移动到新数组中;否则跳过即可。但是很遗憾,题目中已经明确给出了要求,不允许创建新的数组空间,那我们就只能在原数组上进行操作了。

那么在这里我们就可以使用双指针法,也就是创建两个变量src和dst,如果src指向值为val,那就让它自增;否则就让numsdst = numssrc,然后二者分别自增即可。这样最后只要返回dst即可。

请读者思考如何实现这段代码,我给出我的示例:

cpp 复制代码
int removeElement(int* nums, int numsSize, int val) {
    int src = 0;
    int dst = 0;
    for(int i = 0; i < numsSize; i++){
        if(nums[src] == val){
            src++;
        }else{
            nums[dst] = nums[src];
            src++;
            dst++;
        }
    }
    return dst;
}

二、经典算法OJ题:合并两个有序数组

这道题的链接如下:

88. 合并两个有序数组 - 力扣(LeetCode)

题目描述如下:

同样,这道题的思路也很简单,我们完全可以给两个数组一人一个指针,然后比对二者指向的值的大小,然后按照顺序将其填充到融合的新数组中。但是同样遗憾的是,题目中明确指出让我们将数据都存储在nums1之中,那么此时我们该如何操作呢?

显然我们可以不管三七二十一,直接把nums2数组中的数据全部填充到nums1数组之中,然后使用我们前面讲过的排序算法进行排序,但是由于我们之前讲过的冒泡排序属于效率较为低下的算法,它无可避免的会影响到我们代码整体的运行速度。

此时我们其实可以借鉴一下我们刚开始的思路,我们不必让两个指针都指向最前面的元素,恰恰相反,我们可以让其指向数组的最后一个元素,然后让二者比大小,谁更大就被放在最后面,这样最后一定可以完成。那么这段代码应该如何实现呢?我给出一段示例代码:

cpp 复制代码
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {
    int i = m - 1;  
    int j = n - 1; 
    int k = m + n - 1;  
    while (j >= 0) {
        if (i >= 0 && nums1[i] > nums2[j]) {
            nums1[k--] = nums1[i--];
        } else {
            nums1[k--] = nums2[j--];
        }
    }
}

三、关于顺序表的问题和思考

首先,在涉及到顺序表中间以及头部的插入删除时,时间复杂度为O(n),关于这个时间复杂度我们之后会进行详细说明。其次,在增容时我们需要申请新空间,拷贝数据,释放旧空间,这对于我们的性能有着不小的消耗。最后,我们在增容的时候一般是二倍增长,这就导致了一定程度上的空间浪费。

那么我们该如何解决上述问题呢?很简单,我们需要一种新的数据结构,也就是链表,那么关于链表究竟是什么?我们且听下回分解!


总结

本文通过两道力扣算法题介绍了顺序表的经典处理技巧。第一题"移除元素"采用双指针法直接在原数组操作,第二题"合并有序数组"通过逆向双指针实现高效合并。文章还分析了顺序表在插入删除、空间扩容等方面存在的性能问题,并指出链表结构将是解决这些问题的方向。这两道题目展示了顺序表的基本操作思路,为后续学习更复杂的数据结构奠定了基础。

相关推荐
To_OC7 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
炸膛坦客8 小时前
单片机/C/C++八股:(二十六)IIC 专题(I²C)---- 上集
c语言·c++·单片机
旖-旎8 小时前
LeetCode 518:零钱兑换||(完全背包)—— 题解
c++·算法·leetcode·动态规划·背包问题
灯澜忆梦8 小时前
GO_并发编程---定时器
开发语言·后端·golang
-银雾鸢尾-8 小时前
C#中的StringBuilder相关方法
开发语言·c#
To_OC8 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
-银雾鸢尾-8 小时前
C#中结构体与类的区别;抽象类与接口的区别
开发语言·c#
delishcomcn9 小时前
AI视觉识别+分切算法:电化铝缺陷检测与裁切一体化解锁
人工智能·算法
触底反弹9 小时前
深入理解大模型采样:Temperature、Top-K、Top-P 的原理与实战
人工智能·算法·面试
大模型码小白9 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程