【数据结构】双向链表

  • 双向链表的结构体定义
  • 初始化双向链表
  • 头插法构建双向链表
  • 尾插法构建双向链表
  • 双向链表的插入操作
  • 双向链表的删除操作
  • 双向链表的遍历操作
  • 主函数调用

目录:


各部分实现:

双向链表的结构体定义

双向链表的每个结点需要连接前一个结点和后一个结点,所以需要定义两个两个指针域,分别指向前一个结点和后一个结点。

typedef struct tagNode
{
    int data;
    struct tagNode *pre,*next;
}Node,*LinkList;

初始化双向链表

void InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));
    (*L)->next=(*L)->pre=NULL;
}

头插法构建双向链表

利用头插法构建双向链表需要判断插入的元素是否是第一个插入的元素。因为使用头插法对双向链表插入时需要对两头的指针进行调节,而当原链表为空时,只需要对一边的指针进行调节即可。

void CreateHeadList(LinkList L,int n)//头插法
{
    LinkList p;
    while(n--)
    {
        p=(LinkList)malloc(sizeof(Node));
        scanf("%d",&p->data);
        p->next=L->next;
        if(L->next)//链表中已有元素
            L->next->pre=p;
        L->next=p,p->pre=L;
    }
}

尾插法构建双向链表

尾插法构建双向链表时永远在链表的最后进行插入,所以需要对链表的最后一个结点的指向下一个结点的指针域进行调节即可。

void CreateTailList(LinkList L,int n)//尾插法
{
    LinkList p,h;
    h=L;
    while(n--)
    {
        p=(LinkList)malloc(sizeof(Node));
        scanf("%d",&p->data);
        p->next=NULL;
        h->next=p;
        p->pre=h;
        h=p;
    }
}

双向链表的插入操作

具体插入方法与头插法类似。

void InsertList(LinkList L,int i,int e)
{
    LinkList s,p=L;
    while(p!=NULL&&i>1)
    {
        p=p->next;
        i--;
    }
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    if(p->next)//当p不是头结点时
        p->next->pre=s;
    s->pre=p,p->next=s;
}

双向链表的删除操作

首先要找到要删除的那个结点,为方便删除操作,找到要删除结点的前驱结点,将要删除的结点的前驱结点的后驱指针指向要删除的结点的后驱结点,然后将要删除的结点的后驱结点的前驱指针指向删除结点的前驱。

void DeleteList(LinkList L,int e)
{
    LinkList p=L;
    while(p->next&&p->next->data!=e)
    {
        p=p->next;
    }
    p->next=p->next->next;
    p->next->pre=p;
}

双向链表的遍历操作

void TraverseList(LinkList L)
{
    LinkList p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
}

主函数调用

int main()
{
    int n,i,e;
    LinkList L;
    InitList(&L);
    scanf("%d%d%d",&n,&i,&e);
    CreateTailList(L,n);
    InsertList(L,i,e);
    TraverseList(L);
    printf("\n");
    DeleteList(L,e);
    TraverseList(L);
    return 0;
}

全部代码:

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

typedef struct tagNode
{
    int data;
    struct tagNode *pre,*next;
}Node,*LinkList;

void InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node));
    (*L)->next=(*L)->pre=NULL;
}

void CreateHeadList(LinkList L,int n)//头插法
{
    LinkList p;
    while(n--)
    {
        p=(LinkList)malloc(sizeof(Node));
        scanf("%d",&p->data);
        p->next=L->next;
        if(L->next)//链表中已有元素
            L->next->pre=p;
        L->next=p,p->pre=L;
    }
}

void CreateTailList(LinkList L,int n)//尾插法
{
    LinkList p,h;
    h=L;
    while(n--)
    {
        p=(LinkList)malloc(sizeof(Node));
        scanf("%d",&p->data);
        p->next=NULL;
        h->next=p;
        p->pre=h;
        h=p;
    }
}

void InsertList(LinkList L,int i,int e)
{
    LinkList s,p=L;
    while(p!=NULL&&i>1)
    {
        p=p->next;
        i--;
    }
    s=(LinkList)malloc(sizeof(Node));
    s->data=e;
    s->next=p->next;
    if(p->next)//当p不是头结点时
        p->next->pre=s;
    s->pre=p,p->next=s;
}

void DeleteList(LinkList L,int e)
{
    LinkList p=L;
    while(p->next&&p->next->data!=e)
    {
        p=p->next;
    }
    p->next=p->next->next;
    p->next->pre=p;
}

void TraverseList(LinkList L)
{
    LinkList p=L->next;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
}
int main()
{
    int n,i,e;
    LinkList L;
    InitList(&L);
    scanf("%d%d%d",&n,&i,&e);
    CreateTailList(L,n);
    InsertList(L,i,e);
    TraverseList(L);
    printf("\n");
    DeleteList(L,e);
    TraverseList(L);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值