G
N
I
D
A
O
L

【数据结构-链表】链表的基本操作

编写插入函数和删除函数的思路:

  • 先考虑一般情况;
  • 再考虑在链表头部的操作;
  • 最后考虑在链表尾部的操作。

1 单向链表

1.1 有头结点的单向链表

1.1.1 数据结构定义

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

1.1.2 初始化建立链表

  • 头插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head;
    int x;

    // 建立头结点
    head = (LinkList) malloc(sizeof(LinkList));
    head->next = NULL;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = head->next; // 新结点的指针域指向头结点的后继结点
        head->next = newNode; // 头结点的指针域指向新结点
    }
    
    return L;
}
  • 尾插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head, *tail;
    int x;

    // 建立头结点
    head = (LinkList) malloc(sizeof(LinkList));
    head->next = NULL;
    tail = head;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = NULL;
        tail->next = newNode; // 原先尾结点的指针域指向新结点
        tail = newNode; // 尾指针指向新结点
    }
    
    return L;
}

1.1.3 按序号查找结点

LinkNode *GetNumNode (LinkList &L, int pos){
    LinkNode *findNode = L; // 初始指向头结点
    
    if (pos == 0) // 第 0 个结点即头结点
        return L;
    else if (pos < 0) // 必须为非负值
        return NULL;
    
    while ((findNode != NULL) && (pos != 0)){
        findNode = findNode->next;
        pos--;
    }
    return findNode;
}

1.1.4 按值查找结点

LinkNode *GetDataNode (LinkList &L, const int x){
    LinkNode *findNode = L;
    
    while ((findNode != NULL) && (findNode->data != x))
        findNode = findNode->next;

    return findNode;
}

1.1.5 插入操作

  • 新结点插入到第 pos 个位置上(找到其前驱结点即第 pos-1 个结点,进行后插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
    if (posPrev == NULL)
        return false;
    posNode = posPrev->next;
    
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->next = posNode; // 新结点的指针域指向原先第 pos 个结点
    posPrev->next = newNode; // 第 pos-1 个结点的指针域指向新结点
    
    return true;
}
  • 新结点插入到第 pos 个位置上(找到该结点即第 pos 个结点,进行伪前插操作,实质是新结点插入到第 pos 个结点的后面,然后交换数据域):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posNext = posNode->next; // 记录第 pos+1 个结点
    
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = posNode->data; // 交换数据,posNode 变为新结点,newNode 变为旧结点
    newNode->next = posNext; 
    posNode->data = x;
    posNode->next = newNode; 
    
    return true;
}

1.1.6 删除操作

  • 删除第 pos 个结点(找到其前驱结点即第 pos-1 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0) // 不能删除头结点
        return false;
    
    posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
    if (posPrev == NULL)
        return false;
    posNode = posPrev->next; // 记录第 pos 个结点
    posNext = posNode->next; // 记录第 pos+1 个结点
    
    posPrev->next = posNext; // 第 pos-1 个结点的指针域指向原先第 pos 个结点的后继结点(即原先第 pos+1 个结点)
    free(posNode);
    
    return true;
}
  • 删除第 pos 个结点(找到该结点即第 pos 个结点,将其后继结点的值赋值给第 pos 个结点,然后删除其后继结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posNext; // 记录第 pos+1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) // 不能删除头结点
        return false;
    
    posNode = GetNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posNext = posNode->next; // 记录第 pos+1 个结点
    
    if (posNext != NULL){ // 如果第 pos 个结点不是最后一个结点
        posNode->data = posNext->data; // 将其后继结点的值赋值给第 pos 个结点
        posNode->next = posNext->next; // 更新指针域
        free(posNext);
    }
    else{ // 如果第 pos 个结点是最后一个结点
        free(posNode);
        前驱结点的指针域 = NULL; // 这里还是需要再遍历一遍链表找到前驱结点,比较麻烦
    }
    
    return true;
}

1.2 无头结点的单向链表

1.2.1 数据结构定义

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

1.2.2 初始化建立链表

  • 头插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head;
    int x;

    // 建立第一个结点
    x = 读入数据;
    head = (LinkList) malloc(sizeof(LinkList));
    head->data = x;
    head->next = NULL;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = head;
        head = newNode; // 头指针指向新结点
        L = head; // 更新头指针(即链表的入口)
    }
    
    return L;
}
  • 尾插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head, *tail;
    int x;

    // 建立第一个结点
    x = 读入数据;
    head = (LinkList) malloc(sizeof(LinkList));
    head->data = x;
    head->next = NULL;
    tail = head;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = NULL;
        tail->next = newNode; // 原先尾结点的指针域指向新结点
        tail = newNode; // 尾指针指向新结点
    }
    
    return L;
}

1.2.3 按序号查找结点

LinkNode *GetNumNode (LinkList &L, int pos){
    LinkNode *findNode = L; // 初始时指向链表头部
    
    if (pos < 1) // 必须为非负值
        return NULL;
    
    while ((findNode != NULL) && (pos != 0)){
        findNode = findNode->next;
        pos--;
    }
    return findNode;
}

1.2.4 按值查找结点

LinkNode *GetDataNode (LinkList &L, const int x){
    LinkNode *findNode = L; // 初始时指向链表头部
    
    while ((findNode != NULL) && (findNode->data != x))
        findNode = findNode->next;

    return findNode;
}

1.2.5 插入操作

  • 新结点插入到第 pos 个位置上(找到其前驱结点即第 pos-1 个结点,进行后插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    if (pos == 1){ // 如果要插入到第 1 个位置
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = L; // 指针域指向头结点
        L = newNode; // 更新头指针(即链表的入口)
    }
    else{
        posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
        if (posPrev == NULL)
            return false;
        posNode = posPrev->next; // 记录第 pos 个结点
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->next = posNode; // 新结点的指针域指向原先第 pos 个结点
        posPrev->next = newNode; // 第 pos-1 个结点的指针域指向新结点
    }
    
    return true;
}
  • 新结点插入到第 pos 个位置上(找到该结点即第 pos 个结点,进行伪前插操作,实质是新结点插入到第 pos 个结点的后面,然后交换数据域):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posNext = posNode->next;
    
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = posNode->data; // 交换数据,posNode 变为新结点,newNode 变为旧结点
    newNode->next = posNext; 
    posNode->data = x;
    posNode->next = newNode; 
    
    return true;
}

1.2.6 删除操作

  • 删除第 pos 个结点(找到其前驱结点即第 pos-1 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0)
        return false;
    
    if (pos == 1){ // 如果要删除第 1 个结点
        posNext = L->next; // 记录第 2 个结点
        free(L);
        L = posNext; // 头指针指向第 2 个结点
    }
    else{
        posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
        if (posPrev == NULL)
            return false;
        posNode = posPrev->next; // 记录第 pos 个结点
        posNext =  posNode->next; // 记录第 pos+1 个结点
        posPrev->next = posNext; // 第 pos-1 个结点的指针域指向原先第 pos 个结点的后继结点(即原先第 pos+1 个结点)
        free(posNode);
    }
    
    return true;
}
  • 删除第 pos 个结点(找到该结点即第 pos 个结点,将其后继结点的值赋值给第 pos 个结点,然后删除其后继结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posNext; // 记录第 pos+1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0)
        return false;
    
    posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posNext = posNode->next; // 记录第 pos+1 个结点
    
    if (posNext != NULL){ // 如果第 pos 个结点不是最后一个结点
        posNode->data = posNext->data; // 将其后继结点的值赋值给第 pos 个结点
        posNode->next = posNext->next; // 更新指针域
        free(posNext);
    }
    else{ // 如果第 pos 个结点是最后一个结点
        free(posNode);
        前驱结点的指针域 = NULL; // 这里还是需要再遍历一遍链表找到前驱结点,比较麻烦
    }
    
    return true;
}

2 双向链表

2.1 有头结点的双向链表

2.1.1 数据结构定义

typedef struct LinkNode{
    int data;
    LinkNode *prev;
    LinkNode *next;
} *LinkNode, LinkList;

2.1.2 初始化建立链表

  • 头插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head;
    int x;

    // 建立头结点
    head = (LinkList) malloc(sizeof(LinkList));
    head->prev = NULL;
    head->next = NULL;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = head;
        newNode->next = head->next; // 新结点的指针域指向头结点的后继结点
        head->next = newNode; // 头结点的指针域指向新结点
    }
    
    return L;
}
  • 尾插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head, *tail;
    int x;

    // 建立头结点
    head = (LinkList) malloc(sizeof(LinkList));
    head->prev = NULL;
    head->next = NULL;
    tail = head;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = tail;
        newNode->next = NULL;
        tail->next = newNode; // 原先尾结点的指针域指向新结点
        tail = newNode; // 尾指针指向新结点
    }
    
    return L;
}

2.1.3 按序号查找结点

LinkNode *GetNumNode (LinkList &L, int pos){
    LinkNode *findNode = L; // 初始指向头结点
    
    if (pos == 0) // 第 0 个结点即头结点
        return L;
    else if (pos < 0) // 必须为非负值
        return NULL;
    
    while ((findNode != NULL) && (pos != 0)){
        findNode = findNode->next;
        pos--;
    }
    return findNode;
}

2.1.4 按值查找结点

LinkNode *GetDataNode (LinkList &L, const int x){
    LinkNode *findNode = L;
    
    while ((findNode != NULL) && (findNode->data != x))
        findNode = findNode->next;

    return findNode;
}

2.1.5 插入操作

  • 新结点插入到第 pos 个位置上(找到其前驱结点即第 pos-1 个结点,进行后插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
    if (posPrev == NULL)
        return false;
    posNode = posPrev->next; // 记录第 pos 个结点
    
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->prev = posPrev; // 新结点的前驱指针域指向第 pos-1 个结点
    newNode->next = posNode; // 新结点的后继指针域指向第 pos 个结点
    posPrev->next = newNode; // 第 pos-1 个结点的后继指针域指向新结点
    posNode->prev = newNode; // 第 pos 个结点的前驱指针域指向新结点
    
    return true;
}
  • 新结点插入到第 pos 个位置上(找到该结点即第 pos 个结点,进行前插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) // 不能插在头结点的位置上
        return false;
    
    posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posPrev = posNode->prev; // 记录第 pos-1 个结点
    
    newNode = (LinkNode *) malloc(sizeof(LinkNode));
    newNode->data = x;
    newNode->prev = posPrev; // 新结点的前驱指针域指向第 pos-1 个结点
    newNode->next = posNode; // 新结点的后继指针域指向第 pos 个结点
    posPrev->next = newNode; // 第 pos-1 个结点的后继指针域指向新结点
    posNode->prev = newNode; // 第 pos 个结点的前驱指针域指向新结点
    
    return true;
}

2.1.6 删除操作

  • 删除第 pos 个结点(找到其前驱结点即第 pos-1 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0) // 不能删除头结点
        return false;
    
    posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
    if (posPrev == NULL)
        return false;
    posNode = posPrev->next; // 记录第 pos 个结点
    posNext = posNode->next; // 记录第 pos+1 个结点
    posPrev->next = posNext; // 第 pos-1 个结点的后继指针域指向原先第 pos 个结点的后继结点(即原先第 pos+1 个结点)
    posNext->prev = posPrev; // 第 pos+1 个结点的前驱指针域指向原先第 pos 个结点的前驱结点(即原先第 pos-1 个结点)
    free(posNode);
    
    return true;
}
  • 删除第 pos 个结点(找到该结点即第 pos 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posNext; // 记录第 pos+1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    
    if (pos <= 0) // 不能删除头结点
        return false;
    
    posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
    if (posNode == NULL)
        return false;
    posNext = posNode->next; // 记录第 pos+1 个结点
    posPrev = posNode->prev; // 记录第 pos-1 个结点
    
    if (posNext != NULL){ // 如果第 pos 个结点不是最后一个结点
        posPrev->next = posNext;
        posNext->prev = posPrev;
        free(posNode);
    }
    else{ // 如果第 pos 个结点是最后一个结点
        posPrev->next = NULL;
        free(posNode);
    }
    
    return true;
}

2.2 无头结点的双向链表

2.2.1 数据结构定义

typedef struct LinkNode{
    int data;
    LinkNode *prev;
    LinkNode *next;
} *LinkNode, LinkList;

2.2.2 初始化建立链表

  • 头插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head;
    int x;

    // 建立第一个结点
    x = 读入数据;
    head = (LinkList) malloc(sizeof(LinkList));
    head->data = x;
    head->prev = NULL;
    head->next = NULL;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = NULL;
        newNode->next = head;
        head = newNode; // 头指针指向新结点
        L = head; // 更新头指针(即链表的入口)
    }
    
    return L;
}
  • 尾插法:
LinkList InitList (LinkList &L){
    LinkNode *newNode, *head, *tail;
    int x;

    // 建立第一个结点
    x = 读入数据;
    head = (LinkList) malloc(sizeof(LinkList));
    head->data = x;
    head->prev = NULL;
    head->next = NULL;
    tail = head;
    L = head;
    
    while (不符合终止条件){
        x = 读入数据;
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = tail;
        newNode->next = NULL;
        tail->next = newNode; // 原先尾结点的指针域指向新结点
        tail = newNode; // 尾指针指向新结点
    }
    
    return L;
}

2.2.3 按序号查找结点

LinkNode *GetNumNode (LinkList &L, int pos){
    LinkNode *findNode = L; // 初始时指向链表头部
    
    if (pos < 1) // 必须为非负值
        return NULL;
    
    while ((findNode != NULL) && (pos != 0)){
        findNode = findNode->next;
        pos--;
    }
    return findNode;
}

2.2.4 按值查找结点

LinkNode *GetDataNode (LinkList &L, const int x){
    LinkNode *findNode = L; // 初始时指向链表头部
    
    while ((findNode != NULL) && (findNode->data != x))
        findNode = findNode->next;

    return findNode;
}

2.2.5 插入操作

  • 新结点插入到第 pos 个位置上(找到其前驱结点即第 pos-1 个结点,进行后插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    
    if (pos <= 0) 
        return false;
    
    if (pos == 1){ // 如果要插入到第 1 个位置
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = NULL;
        newNode->next = L;
        L = newNode; // 更新头指针(即链表的入口)
    }
    else{
        posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
        if (posPrev == NULL)
            return false;
        posNode = posPrev->next; // 记录第 pos 个结点
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = posPrev; // 新结点的前驱指针域指向第 pos-1 个结点
        newNode->next = posNode; // 新结点的后继指针域指向第 pos 个结点
        posPrev->next = newNode; // 第 pos-1 个结点的后继指针域指向新结点
        posNode->prev = newNode; // 第 pos 个结点的前驱指针域指向新结点
    }
    
    return true;
}
  • 新结点插入到第 pos 个位置上(找到该结点即第 pos 个结点,进行前插操作):
bool InsertNode (LinkList &L, int pos, const int x){
    LinkNode *newNode; // 新结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posPrev; // 记录第 pos+1 个结点
    
    if (pos <= 0) 
        return false;
    
    if (pos == 1){ // 如果要插入到第 1 个位置
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = NULL;
        newNode->next = L;
        L = newNode; // 更新头指针(即链表的入口)
    }
    else{
        posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
        if (posPrev == NULL)
            return false;
        posPrev = posNode->prev; // 记录第 pos-1 个结点
        newNode = (LinkNode *) malloc(sizeof(LinkNode));
        newNode->data = x;
        newNode->prev = posPrev; // 新结点的前驱指针域指向第 pos-1 个结点
        newNode->next = posNode; // 新结点的后继指针域指向第 pos 个结点
        posPrev->next = newNode; // 第 pos-1 个结点的后继指针域指向新结点
        posNode->prev = newNode; // 第 pos 个结点的前驱指针域指向新结点
    }
    
    return true;
}

2.2.6 删除操作

  • 删除第 pos 个结点(找到其前驱结点即第 pos-1 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posPrev; // 记录第 pos-1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posNext; // 记录第 pos+1 个结点
    
    if (pos <= 0) 
        return false;
    
    if (pos == 1){ // 如果要删除第 1 个结点
        posNext = L->next; // 记录第 2 个结点
        free(L);
        L = posNext; // 更新头指针(即链表的入口)
    }
    else{
        posPrev = GetNumNode(L, pos-1); // 先找到第 pos-1 个结点
        if (posPrev == NULL)
            return false;
        posNode = posPrev->next; // 记录第 pos 个结点
        posNext = posNode->next; // 记录第 pos+1 个结点
        posPrev->next = posNext; // 第 pos-1 个结点的后继指针域指向原先第 pos 个结点的后继结点(即原先第 pos+1 个结点)
        posNext->prev = posPrev; // 第 pos+1 个结点的前驱指针域指向原先第 pos 个结点的前驱结点(即原先第 pos-1 个结点)
        free(posNode);
    }
    
    return true;
}
  • 删除第 pos 个结点(找到该结点即第 pos 个结点):
bool DeleteNode (LinkList &L, int pos){
    LinkNode *posNext; // 记录第 pos+1 个结点
    LinkNode *posNode; // 记录第 pos 个结点
    LinkNode *posPrev; // 记录第 pos-1 个结点
    
    if (pos <= 0) 
        return false;
    
    if (pos == 1){ // 如果要删除第 1 个结点
        posNext = L->next; // 记录第 2 个结点
        free(L);
        L = posNext; // 更新头指针(即链表的入口)
    }
    else{
        posNode = GetNumNode(L, pos); // 先找到第 pos 个结点
        if (posNode == NULL)
            return false;
        posNext = posNode->next; // 记录第 pos+1 个结点
        posPrev = posNode->prev; // 记录第 pos-1 个结点
        
        if (posNext != NULL){ // 如果第 pos 个结点不是最后一个结点
            posPrev->next = posNext;
            posNext->prev = posPrev;
            free(posNode);
        }
        else{ // 如果第 pos 个结点是最后一个结点
            posPrev->next = NULL;
            free(posNode);
        }
    }
    
    return true;
}
posted @ 2022-10-27 09:52  漫舞八月(Mount256)  阅读(100)  评论(0编辑  收藏  举报