手撕顺序表2

在上节博客中,我为大家讲解了顺序表的定义、初始化、与顺序表的增容。
今天我来为大家补充顺序表的各种操作讲解

前面,我们已经对顺序表进行了容量为16个字节的增容。现在,我们准备往顺序表中的空间存放我们想要存放的数据。

顺序表的尾插

这是我们增容后的顺序表
在这里插入图片描述

所以我们在下标为size的地方插入我们想要的数据即可

struct SL
{
   int *arr;
   int size;
   int capacity;
};
 void slpushback(struct SL * ps,int x)//ps接收关于sl的结构体指针,x为4
 {
    ps->arr[ps->size] = 4;
    ps->size++;//每次插入一个数据,size都需要++,用来表示顺序表的有效数组多了一个
 }
int main()
{
    Sl sl;//定义结构体变量,假设capacity已经为4了
    slpushback(&sl,4);//4是我们想要插入的数据
}

自此,size就指向了下标为1的地方
在这里插入图片描述
再插三次,就会把顺序表插满,自此size和capacity都指向了4的位置,就证明顺序表已经满了,再插进去,就需要capacity扩容!!!!

顺序表的尾删

假设我们现在插了多个数据,就比如下图
在这里插入图片描述
我们想要删除尾部“2”这个数据怎么办?
答案是:我们只能通过size向左平移一位(也就是size–),把2这个数字覆盖,然后打印的时候不让下标走到size,这也叫障眼法吧,就比如下图
在这里插入图片描述
虽然已经插入了3个数字,size指向3没错,但是我们现在要尾删,所以只能让size–,让size指向2这个位置

void SLpopback(SL * ps)
{
   ps->size--;//先让size减一
   
}
void print(SL * ps)
{
    int i = 0;
    for(i = 0;i<ps->size;i++)
    {
       printf("%d ",ps->arr[i]);//打印出来的结果为4 3 
    } 
}
int main()
{
   SL sl;
   SLpopback(&sl);
   print(&sl);
   return 0;
}

如上面代码所示,让size减一,i遍历到size后一位,就实现顺序表打印少打一位。就类似于尾删。

顺序表的头插

顺序表的头插就是把以往的数据往后移一位,然后把向头插的数据插入到下标为0的位置中。

在这里插入图片描述
如图,就是为头插的全部过程,先把数据都往后移一个位置,再把想要插入的数据插入下标为0的位置
需要注意的是,每次插入数据都得判断一下顺序表是否满了。如果满了,需要先扩容,再插入数据。
接下来,代码实现一下

void SLpushfront(SL * ps,SLdatatype x);//传指向那个顺序表的地址,还有想插入的数据x
{
   zengrong(ps);//判断容量是否充足
    int i = ps->size;
    for(i = ps->size;i>=0;i--)
    {
        arr[i+1] = arr[i];//把i位置的数据赋值给i+1
    }
    ps->arr[0] = x;//在下标为0的位置插我们想插的数据
    ps->size++;//每插入一个数据,size要加加,每删除一个数据,size要减减
   
}

这里需要注意一下,一定是从最后面开始往后平移,如果从最开始的数据开始平移,就会覆盖后面的数据

如果你看到这里,这边博主建议你自己画个图,思考为什么不能从最前前面开始平移,一定要自己动手!!!!!!

顺序表的头删在这里插入图片描述

上面讲过了头插,现在头删也就是另一种思路,就是把头位置后面的数据,都往前移一个位置,用第二个数据把头数据给覆盖了,也就做到了头删,这边的话,就得从前面开始平移,从后面开始平移会造成数据的覆盖。

顺序表在指定位置插入

那么有同学想问,我不拘泥于头部和尾部,我们想在我们自己指定的位置插入数据和删除数据怎么办?
在这里插入图片描述

假如,我们想在3这个位置插入一个9怎么办?如图,就得把3后面的数据都往后平移一个位子,还有,插入数据需要判断顺序表是否满了,满了就需要增容,并且插入数据时候后size需要加加。

接下来,我们代码实现一下

SLpushpop(SL * ps,SLdatatype x,int bos)//最后面的bos就是想要在bos位置插入 
{
    int i = ps->size-1;//让i指向size-1的位置,然后size-1的位置赋值给size的位置
    for(i = ps->size-1;i>bos;i--)
    {
        arr[i+1] = arr[i];//让下标为bos后的数据向后平移一位,所以i>bos就可以进入循环
    }
    ps->arr[ps->bos] = x;//在下标为bos的位置插入x
    ps->size++;//最后size要加加
}

顺序表在指定位置删除

跟前面差不多,顺序表在指定位置删除跟上面也是这个逻辑,也就是把bos后一位的数据往bos放,以此类推
在这里插入图片描述
如图,就是在3这个位置删除数据的演示
在这里插入图片描述

i定义在bos的位置,i+1就在bos的后一个位置,然后,再让i+1位置的数据挪到i位置上去,i最大只能取到size-1的位置,因为i+1就刚好等于size,size下标没有数据

上代码

SLpopbos(SL * ps,SLdatatype x,int bos)
{
    int i = bos;
    for(i = bos;i<ps->size-1;i++)
    {
       arr[i+1] = arr[i];
    }
    ps->size--;
}

尾声

顺序表的博客就写到这里啦,博主期待与你们并肩作战,干掉下一个单链表!!

### 华为OD模式下的链表代码问题 在华为OD模式的面试中,链表作为经典的数据结构之一,经常被用来考察候选人的基本功以及对复杂场景的理解能力。以下是针对链表相关的常见算法和数据结构问题及其解决方案。 #### 常见链表操作 链表的操作主要包括以下几个方面: - **单向链表反转** 反转一个单向链表是一个经典的题目,在实际应用中有广泛用途。可以通过迭代的方式实现该功能[^1]。 ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def reverse_list(head: ListNode) -> ListNode: prev = None current = head while current is not None: next_node = current.next current.next = prev prev = current current = next_node return prev ``` - **查找中间节点** 使用快慢指针的方法可以在一次遍历中找到链表的中间节点[^2]。 ```python def find_middle_node(head: ListNode) -> ListNode: slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow ``` - **删除倒数第N个节点** 删除链表中的倒数第 N 个节点通常需要用到双指针技巧来定位目标位置。 ```python def remove_nth_from_end(head: ListNode, n: int) -> ListNode: dummy = ListNode(0) dummy.next = head first = second = dummy for _ in range(n + 1): first = first.next while first: first = first.next second = second.next second.next = second.next.next return dummy.next ``` #### LRU缓存机制与链表的关系 LRU(Least Recently Used)是一种常见的缓存淘汰策略,其实现往往依赖于双向链表和哈希表相结合的设计思路。通过维护一个按访问顺序排列的双向链表,可以快速更新最近使用的元素并移除最久未使用的项。 ```python from collections import OrderedDict class LRUCache: def __init__(self, capacity: int): self.cache = OrderedDict() self.capacity = capacity def get(self, key: int) -> int: if key not in self.cache: return -1 self.cache.move_to_end(key) return self.cache[key] def put(self, key: int, value: int) -> None: if key in self.cache: self.cache.move_to_end(key) self.cache[key] = value if len(self.cache) > self.capacity: self.cache.popitem(last=False) ``` 上述代码展示了如何利用 `OrderedDict` 来模拟 LRU 缓存的行为,其中涉及到了链表的相关概念和技术细节。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值