• DS-4-单链表的各种插入与删除的实现


    typedef struct LNode {
        int data;
        struct LNode *next;
    }LNode, *LinkList;

    带头结点的按位序插入:

    //在第i个位置插入元素e
    bool ListInsert(LinkList &L, int i, char e) {
        if (i < 1)
            return false;
    
        LNode *p;        //p指向当前扫描到的结点
        int j = 0;        //当前p指向的是第几个结点
        p = L;            //L指向头结点,第0个结点
        while (p != NULL && j < i - 1) {        //循环找到要插入结点的前一个结点
            p = p->next;
            j++;
        }
    
        if (p == NULL)        //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
            return false;
        LNode *s = (LNode *)mallocsizeof(LNode)); //新结点
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }

    不带头结点的按位序插入:(对于插入第一个结点时需要特殊处理,其他部分与带头结点的一样)

    bool ListInsert(LinkList &L, int i, char e) {
        if (i == 1) {
            LNode *s = (LNode *)mallocsizeof(LNode));
            s->data = e;
            s->next = L;
            L = s;
            return true
        }
        if (i < 1)
            return false;
    
        LNode *p;        //p指向当前扫描到的结点
        int j = 0;        //当前p指向的是第几个结点
        p = L;            //L指向头结点,第0个结点
        while (p != NULL && j < i - 1) {        //循环找到要插入结点的前一个结点
            p = p->next;
            j++;
        }
    
        if (p == NULL)        //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
            return false;
        LNode *s = (LNode *)mallocsizeof(LNode)); //新结点
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }

    指定结点的后插操作:

    //在p结点之后插入元素e
    bool InsertNextNode(LNode *p, char e) {
        if (p == NULL)
            return false;
        LNode *s = (LNode *)mallocsizeof(LNode));
        if (s == NULL)
            return false;    //内存分配失败
        s->data = e;
        s->next = p->next;
        p->next = s;
        return true;
    }

    这里的后插操作其实就相当于已经找到了p,和按位序插入while循环后边的代码一样了,所以按位序插入后边部分可以调用这个函数:

    //在第i个位置插入元素e
    bool ListInsert(LinkList &L, int i, char e) {
        if (i < 1)
            return false;
    
        LNode *p;        //p指向当前扫描到的结点
        int j = 0;        //当前p指向的是第几个结点
        p = L;            //L指向头结点,第0个结点
        while (p != NULL && j < i - 1) {        //循环找到要插入结点的前一个结点
            p = p->next;
            j++;
        }
      return
    InsertNextNode(p,e);
    }

    指定结点的前插操作:

    如果给了头指针的话,只需要循环查找到要插入结点的前一个结点,然后插入即可

    //在p结点之前插入元素e
    bool InsertPriorNode(LinkList L, LNode *p, char e)

    然而如果不给头指针的话,就需要偷天换日一下,把新结点插入到p结点后边,然后把新结点的数据元素和和p结点互换,逻辑上实现同样的效果

    //在p结点之前插入元素e
    bool InsertPriorNode(LNode *p, char e) {
        if (p == NULL)
            return false;
        LNode *s = (LNode *)mallocsizeof(LNode));
        if (s == NULL)
            return false;    //内存分配失败
        s->next = p->next;
        p->next = s;
        s->data = p->data;
        p->data = e;
        return true;
    }

    如果是直接传入了结点s,道理是一样的;

    //在p结点之前插入结点s
    bool InsertPriorNode(LNode *p, LNode *s) {
        if (p == NULL || s == NULL)
            return false;
        s->next = p->next;
        p->next = s;
        char temp = p->data;
        p->data = s->data;
        s->data = temp;
        return true;
    }

    按位序删除(带头结点):

    前半部分与插入结点一样,先循环查找p

    //删除表L中第i个位置的元素,并用e返回删除元素的值
    bool ListDelete(LinkList &L, int i, char &e) {
        if (i < 1)
            return false;
    
        LNode *p;        //p指向当前扫描到的结点
        int j = 0;        //当前p指向的是第几个结点
        p = L;            //L指向头结点,第0个结点
        while (p != NULL && j < i - 1) {
            p = p->next;
            j++;
        }
    
        if (p == NULL)    
            return false;
        if (p->next == NULL)
            return false;
        LNode *q = p->next;    //令q指向被删除的结点
        e = q->data;        //用e返回被删的值
        p->next = q->next;    //断开连接
        free(q);            //释放被删结点空间
        return true;
    }

    指定结点的删除:

    删除结点p,需要修改其前驱 结点的next指针
    方法1:传入头指针,循环寻找p的前驱结点

    方法2:偷天换日(类似于结点前插的实现)

    下面是方法2的代码实现:

    //删除指定结点p
    bool DeleteNode(LNode *p) {
        if (p == NULL)
            return false;
        LNode *q = p->next;        //令q指向*p的后继结点
        p->data = p->next->data;
        p->next = q->next;
        free(q);
        return true;
    }

    如果p是最后一个结点就只能从表头开始依次寻找p的前驱...

  • 相关阅读:
    定时任务
    ---Ubuntu 连接手机tethering
    ---thunar 文件浏览器的使用!
    ---recovery ui 修改
    ---wordpress 升级遇到的问题!
    ---BD PROCHOT
    ---安装/修复Ubuntu/Ach Linux efi 启动 !!!(包括双系统启动)
    ---sgdisk 分区表
    --- cache PV 丢失或损坏 怎么办
    ---lvm2分区修复问题!
  • 原文地址:https://www.cnblogs.com/swefii/p/13132502.html
Copyright © 2020-2023  润新知