7.0、C语言数据结构——线性表 (3)

7.0、C语言数据结构——线性表 (3)

        我们先来看下单来链表的插入,假设存储元素 e 的结点为 s ,要实现结点 p ,p -> next 和 s 之间逻辑关系的变化,大家参考下图思考一下:

        1. 我们思考后发觉根本用不着惊动其他结点,只需要让 s -> next 和 p -> next 的指针做一点改变; 
        s -> next = p -> next;
        p -> next = s;
        2. 我们通过图片来解读一下这两句代码 ->

单链表数据插入的总结如下:

        1.声明一结点 p 指向链表头结点,初始化 j 从 1 开始;
        2. 当 j < 1 时,就遍历链表,让 p 的指针向后移动,不断指向下一结点,j 累加 1;
        3. 若到链表末尾 p 为空,则说明第 i 个元素不存在;
        4. 否则查找成功,在系统中生成一个空结点 s;
        5. 将数据元素 e 赋值给 s -> data;
        6. 单链表的插入刚才两个标准语句;
        7. 返回成功;

Status ListInsert (LinkList* L , int i , ElemType e) {
    int j;
    LinkList p , s;
    p = *L;
    j = 1;
    while() {
        p = p -> next;
        j++; 
    }
    if(!p || j > i) {
        return ERROR;
    }
    s = (LinkList)malloc(sizeof(Node));
    s -> data = e;
    s -> next = p -> next;
    p -> next = s;
    return OK;
}

单链表删除操作:

        1. 假设元素 a2 的结点为 q ,要实现结点 q 删除单链表的操作,其实就是将它的前驱结点的指针绕过指向后继结点即可;
        2. 那我们所要做的,实际上就是一步:
        可以这样: p -> next = p -> next -> next;
        也可以是:q = p -> next;p -> next = q -> next;
 

单链表第 i 个数据删除结点的算法思路:

        1. 声明结点 p 指向链表第一个结点,初始化 j = 1;
        2. 当 j < 1 时,就遍历链表,让 p 的指针向后移动,不断指向下一结点,j 累加 1;
        3. 若到链表末尾 p 为空,则说明第 i 个元素不存在;
        5.否则查找成功,将欲删除结点 p -> next 赋值给 q ;
        6. 单链表的删除标准语句 p -> next = q -> next;
        7. 将 q 结点中的数据赋值给 e ,作为返回;
        8. 释放q 结点;

Status ListDelete (LinkList* L , int i , ElemType* e) {
    int j;
    LinkList p , q;
    p = *L;
    j = 1;
    while(p->next && j < i) {
        p = p -> next;
        ++j;
    }
    if(!(p -> next) || j > i) {
        return ERROR;
    }
    q = p -> next;
    p -> next = q -> next;
    *e = q -> data;
    free(q);
    return OK;
}

最后单链表和顺序存储效率比较一下得出结论:

        1. 我们最后的环节是效率 PK ,我们发现无论是单链表插入还是删除算法,他们其实都是由两个部分组成:第一部分就是遍历查找第 i 个元素,第二部分就是实现插入和删除元素;
        2.从整个算法来说,我们很容易可以推出他们的时间复杂度都是 O ( n );
        3. 再详细点分析:如果在我们不知道第 i 个元素的指针位置,单链表数据结构在插入和删除操作上,与线性表的顺序存储结构是没有太大优势的;
        4. 但如果,我们希望从第 i 个位置开始,插入连续 10 个元素,对于顺序存储结构意味着,每一次插入都需要移动 n - i 个位置,所以每次都是 O ( n );
        5. 而单链表,我们只需要在第一次时,找到第 i 个位置的指针,此时为 O ( n ),接下来只是简单地通过赋值移动指针而已,时间复杂度都是 O ( 1 );
        6. 显然,对于插入或删除数据越频繁的操作,单链表的效率优势就越明显;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值