4-双链表的操作

1.定义一个双链表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef int ElemType;

/* 定义一个单链表 */
typedef struct DNode {
    /*数据域*/
    ElemType data;
    /*前驱指针域*/
    struct LNode *prior;
    /*后驱指针域*/
    struct LNode *next;
} DNode, *DinkList; /*DNode处理单个节点 ; DinkList处理整个双链表*/


int main() {

    return 0;
}

插入和删除双链表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef int ElemType;

/* 定义一个双链表节点 */
typedef struct DNode {
    ElemType data;            /* 数据域 */
    struct DNode *prior;      /* 前驱指针域 */
    struct DNode *next;       /* 后驱指针域 */
} DNode, *DLinkList;

/* 初始化双链表 */
DLinkList initDLinkList() {
    DLinkList L = (DLinkList ) malloc(sizeof(DNode));
    if (L == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
    L->next = NULL;
    L->prior = NULL;
    return L;
}

/* 获取双链表长度 */
int length(DLinkList L) {
    int len = 0;
    DNode *p = L->next; // 假设L是一个头节点
    while (p != NULL) {
        len++;
        p = p->next;
    }
    return len;
}

/* 按位查找,返回第i个位置的节点指针 */
DNode* getElemByPos(DLinkList L, int i) {
    int j = 0;
    DNode *p = L;
    while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
    return p;
}

/* 在双链表的第i个位置插入元素值为x的节点 */
void insertNode(DLinkList L, int i, ElemType x) {
    if (i < 1 || i > length(L) + 1) {
        printf("无效的位置\n");
        return;
    }
    DNode *p = getElemByPos(L, i - 1);
    /*定义一个要插入的节点指针*/
    DNode *s = (DNode *) malloc(sizeof(DNode));
    if (s == NULL) {
        printf("内存分配失败\n");
        exit(1);
    }
    /*修改s地址上的实际 的值*/
    s->data = x;
    /**/
    s->next = p->next;
    if (p->next != NULL) {
        /*当我们插入新节点 s 后,需要确保新节点 s 成为原来第 i 个节点的前驱节点,因此我们将 p->next->prior 设置为 s。
        更详细的解释:
        新节点 s 将插入到 p 之后,成为新的第 i 个节点。
        原来的第 i 个节点的前驱节点将更新为新节点 s。*/
        p->next->prior = s;
        /*p->next->prior = s;可以改写为:如下代码*/
        //先获取原来i位置上的地址指针 (p->next)
        // 原来i位置上的地址指针  变为了 i+1 的位置
        /*所有  原来i位置上的地址指针的前驱指针域prior 变成了新插入的指针s 的地址*/
        //(p->next)->prior=s;
    }
    s->prior = p;
    p->next = s;
}

/* 删除双链表中第i个位置的节点 */
bool deleteNode(DLinkList L, int i, ElemType *e) {
    if (i < 1 || i > length(L)) {
        return false;
    }
    /*获取 i-1 位序上的节点地址 */
    DNode *p = getElemByPos(L, i - 1);
    /*获取要删除的节点的地址*/
    DNode *q = p->next;
    if (q == NULL) {
        return false;
    }
    /*更新 i-1 的后驱指针域 为 i+1的地址指针*/
    p->next = q->next;
    if (q->next != NULL) {
        q->next->prior = p;
    }
    *e = q->data;
    /*删除q指针*/
    free(q);
    return true;
}

int main() {
    /* 初始化双链表L为一个带头节点的空链表 */
    DLinkList L = initDLinkList();

    /* 插入测试数据 */
    insertNode(L, 1, 10); // 在第1个位置插入10
    insertNode(L, 2, 20); // 在第2个位置插入20
    insertNode(L, 1, 5);  // 在第1个位置插入5

    /* 打印链表 */
    DNode *p = L->next;
    while (p != NULL) {
        printf("%d -> ", p->data);
        p = p->next;
    }
    printf("NULL\n");

    /* 删除节点测试 */
    ElemType e;
    if (deleteNode(L, 2, &e)) {
        printf("已删除节点的值: %d\n", e);
    } else {
        printf("删除失败\n");
    }

    /* 再次打印链表 */
    p = L->next;
    while (p != NULL) {
        printf("%d -> ", p->data);
        p = p->next;
    }
    printf("NULL\n");

    /* 释放链表 */
    p = L;
    while (p != NULL) {
        DNode *temp = p;
        p = p->next;
        free(temp);
    }

    return 0;
}

posted @ 2024-07-08 00:31  成强  阅读(14)  评论(0编辑  收藏  举报