• 第九单元 基本数据结构9.1 线性表(顺序结构)9.2 线性表(链式结构)


    第九单元 基本数据结构

    9.1 线性表(顺序结构)

    线性表可以用普通的一维数组存储。
    你可以让线性表可以完成以下操作(代码实现很简单,这里不再赘述):
    1. 返回元素个数。
    2. 判断线性表是否为空。
    3. 得到位置为 p 的元素。
    4. 查找某个元素。
    5. 插入、删除某个元素:务必谨慎使用,因为它们涉及大量元素的移动。

    9.2 线性表(链式结构)

    (1) 单链表!

    1. 定义:下面有一个空链表,表头叫 head,并且表内没有任何元素。

    1. struct node
    2. {
    3. int value;
    4. node *next;
    5. } arr[MAX];
    6. int top=-1;
    7. node *head = NULL;

    2. 内存分配:在竞赛中不要用 new,也不要用 malloc、calloc——像下面一样做吧。

    1. #define NEW(p) p=&arr[++top];p->value=0;p->next=NULL
    2. node *p;
    3. NEW(head); // 初始化表头
    4. NEW(p); // 新建结点

     

    3. 插入:把 q 插入到 p 的后面。时间复杂度 O(1)。

    1. if (p!=NULL && q!=NULL) // 先判定是否为空指针。如果不是,继续。
    2. {
    3. q->next=p->next;
    4. p->next=q;
    5. }

    4. 删除:把 p 的下一元素删除。时间复杂度 O(1)。

    1. if (p!=NULL && p->next!=NULL) // 先判定是否为空指针。如果不是,继续。
    2. {
    3. node *q=p->next;
    4. p->next=q->next;
    5. // delete(q); // 如果使用动态内存分配,最好将它的空间释放。
    6. }

     5. 查找或遍历:时间复杂度 O(n)。

    1. node *p=first;
    2. while (p!=NULL)
    3. {
    4. // 处理value
    5. // cout<<p->value<<'\t';
    6. p=p->next;
    7. }

    (2) 静态链表

    指针的作用就是存储地址。如果我们找到了替代品,就可以放弃指针了。
    需要把上面的定义改一下:

    1. struct node
    2. {
    3. int value;
    4. int next; // 表示下一元素在arr中的下标
    5. } arr[MAX];

    (3) 循环链表

    和单链表有一个重大区别:单链表最后一个元素的 next 指向 NULL,而循环链表最后一个元素的 next指向 first。
    遍历时要留心,不要让程序陷入死循环。
    一个小技巧:如果维护一个表尾指针 last,那么就可以在 O(1)的时间内查找最后一个元素。同时可以防止遍历时陷入死循环。

    (4) 双链表

    1. 定义:下面有一个空链表,表头叫 first

    1. struct node
    2. {
    3. int value;
    4. node *next, *prev;
    5. } arr[MAX];
    6. int top=-1;
    7. node *first = NULL; // 根据实际需要可以维护一个表尾指针last。

    2. 内存分配:最好不要使用 new 运算符或 malloc、calloc 函数。

    1. #define NEW(p) p=arr+(++top);p->value=0;p->next=NULL;p->prev=NULL
    2. node *p;
    3. NEW(head); // 初始化表头
    4. NEW(p); // 新建结点

    3. 插入:把 q 插入到 p 的后面。时间复杂度 O(1)。

    1. if (p==NULL||q==NULL) // 先判定是否为空指针。如果不是,继续。
    2. {
    3. q->prev=p;
    4. q->next=p->next;
    5. q->next->prev=q;
    6. p->next=q;
    7. }

    4. 删除:把 p 的下一元素删除。时间复杂度 O(1)。

    1. if (p==NULL||p->next==NULL) // 先判定是否为空指针。如果不是,继续。
    2. {
    3. node *q=p->next;
    4. p->next=q->next;
    5. q->next->prev=p;
    6. // delete(q); // 如果使用动态内存分配,最好将它的空间释放。
    7. }

    5. 查找或遍历:从两个方向开始都是可以的。

    (5) 将元素插入到有序链表中*

    1. void insert(const node *head, node *p)
    2. {
    3. node *x, *y;
    4. y=head;
    5. do
    6. {
    7. x=y;
    8. y=x->next;
    9. } while ((y!=NULL) && (y->value < p->value);
    10. x->next=p;
    11. p->next=y;
    12. }

  • 相关阅读:
    Shell 脚本入门 ①
    node.js+express 做301重定向实验
    Training language models to follow instructions with human feedback 论文阅读
    【开题报告】基于SpringBoot的医疗器械出入库系统的设计与实现
    数商云经销商系统促销功能解析,灵活定义促销方案助力家居建材企业抢占市场
    零基础学 Java 编程需要注意哪些事项?
    python调用外部exe程序 等待程序执行完后后 往下运行 直接往下运行
    想用最快的方法从很多名单中搜到符合条件的人
    如何使用Solidity和Hardhat构建你自己的NFT以及NFT交易市场
    期货开户是否有资金门槛?
  • 原文地址:https://blog.csdn.net/zhengheda/article/details/125570483