双链表是一种重要的操作,可以帮助我们更好的理解数据结构和链表,下面我来介绍一下如何实现双链表的增删改查

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

typedef struct LNode
{
    int data;//数据域
    struct LNode* next, *prior;//指针域  前指针和后指针

}LNode,*LinkList;
bool InitLNode(LinkList* L)//初始化
{

    *L = (LNode*)malloc(sizeof(LNode));//创建头结点
    if (*L == NULL)
        return false;
    (*L)->next = NULL;//头结点和下一个结点都为空
    (*L)->prior = NULL;
    return true;
}
void InitNode_tail(LinkList* L)//初始化插入(尾插法)
{
    int i;
    LNode* r = *L;//创建尾指针r

    printf("请输入你要初始化的数据,输入9999退出:\n");
    scanf("%d", &i);
    while (i != 9999)
    {
        LNode* s = (LNode*)malloc(sizeof(LNode));
        s->data = i;//把数据送给s的数据域
        s->next = NULL;//另s指向NULL
        s->prior = r;//把s的前一项指向s的头结点
        r->next = s;//把前一项的尾结点指向s
        r = s;//尾指针向前移
        scanf("%d", &i);
    }
    return;
}
void InitNode_head(LinkList* L)//初始化插入(头插法)
{
    int i;
    printf("请输入你要初始化的数据,输入9999退出:\n");
    scanf("%d", &i);
    while (i != 9999)
    {
        LNode* s = (LNode*)malloc(sizeof(LNode));
        if (s == NULL)//分配失败
            return;
        s->data = i;
        s->next = (*L)->next;
        s->prior = *L;
        (*L)->next = s;
        scanf("%d", &i);
    }
    return;
}
LNode* Find_LNode(LinkList L, int j)//按结点查找
{
    if (j < 1)
        return NULL;
    LNode* p = L;
    int i = 0;
    while (p != NULL && i < j)
    {
        p = p->next;
        i++;
    }
    if(p == NULL)
        return NULL;
    return p;
}
bool InsertLNode_tail(LinkList* L,int n,int n1)//后插操作
{
    if ((*L)->next == NULL || n < 1)
        return false;
    /*LNode* p = *L;
    int j = 0;
    while (p != NULL && j < n)
    {
        p = p->next;
        j++;
    }*/
    LNode* p = Find_LNode(*L, n);//调用查找函数,如果不用函数上面注释的部分也可以
    LNode* s = (LNode*)malloc(sizeof(LNode));
    s->data = n1;

    if (p->next != NULL)
    {
        s->next = p->next;
        s->prior = p;
        p->next->prior = s;
        p->next = s;
    }
    else {
        s->next = NULL;
        s->prior = p;
        p->next = s;
    }
    return true;

}
bool InsertNode_front(LinkList* L, int z, int z1)//前插操作
{
    if (z < 1)
        return false;
    LNode* p = *L;
    int j = 0;
    while (p != NULL && j < z - 1)//也可以调用前面的查找函数
    {
        p = p->next;
        j++;
    }
    if (p->next == NULL)
        return false;
    LNode* s = (LNode*)malloc(sizeof(LNode));
    s->data = z1;
    s->next = p->next;
    p->next->prior = s;
    p->next = s;
    s->prior = p;

    return true;
}
bool DeleteLNode(LinkList* L, int n2)//删除结点
{
    if (n2 < 1)
        return false;
    LNode* p = *L;
    int j = 0;

    while (p != NULL && j < n2-1)//也可以调用前面的查找函数
    {
        p = p->next;
        j++;
    }
    LNode* q = p->next;
    if (q == NULL)
        return false;
    p->next = q->next;
    if(q->next != NULL)
        q->next->prior = p;
    free(q);

    return true;
}
void PrintNode(LinkList L)//打印
{
    if (L->next == NULL)
        return;
    LNode* p = L->next;
    while (p != NULL)
    {        
        printf("%d ", p->data);
        p = p->next;
    }
    return;
}

int main()
{
    LinkList L;//指向双链表的指针
    InitLNode(&L);//初始化
    InitNode_tail(&L);//双链表初始化数据(尾插法)
    //InitNode_head(&L);//双链表初始化数据(头插法)--实现链表逆序的重要操作

    //int j;
    //printf("请输入你要查找的结点\n");
    //scanf("%d", &j);
    //Find_LNode(L, j);//按结点查找

    int n, n1;
    printf("请输入在哪个节点后插入什么数\n");//插入(后)
    scanf("%d %d", &n, &n1);
    InsertLNode_tail(&L, n, n1);//按照结点插入(后插法)

    int z, z1;
    printf("请输入在哪个结点前插入什么数\n");//插入(前)
    scanf("%d %d", &z, &z1);
    InsertNode_front(&L, z, z1);//按照结点插入(前插法)

    int n2;
    printf("请输入你要删除第几个结点\n");//删除
    scanf("%d", &n2);
    DeleteLNode(&L, n2);//删除结点

    PrintNode(L);

    return 0;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐