双向链表的建立插入删除

Posted tianzeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双向链表的建立插入删除相关的知识,希望对你有一定的参考价值。

双向链表简介

  在循环链表中虽然能够实现从任一一结点出发找到其前驱,但时间复杂度是O(n),从表中希望迅速找到其前驱,可为每个结点增加一个指向其前驱的指针prior,这样链表中有两条方向不同的链,称为双向链表

typedef struct Node
{
    int data;
    struct Node *prior,*next;//prior前驱,next后继 
}Node,*DoubleLinkList;

  p指向双向链表中某一结点,以下成立

p->prior->next==p;
p->next->prior==p;

  建立双向链表

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;    
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }    
}

  双向链表的插入

  指针变化情况

技术分享图片技术分享图片

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *prior,*next;//prior前驱,next后继 
}Node,*DoubleLinkList;

void InitDLLinkList(DoubleLinkList *DL)
{
    *DL=(DoubleLinkList)malloc(len);
    (*DL)->next=NULL;
    (*DL)->prior=NULL;
}

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;    
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }    
}

void InDLLinkList(DoubleLinkList DL,int i,int x)
{
    Node *p=DL->next,*s;          //p=DL->next开始,第一个结点开始 
    int k=1;
    if(i<=0)
    {
        printf("You enter location illegal I is too small
");
        return;
    }
    while(p!=DL&&k<i)            //最后一个位置也能插 ,p指向被插入的位置 
    {
        p=p->next;
        k++;
    }
    if(p==DL)
    {
        printf("You enter location illegal I is too big
");
        return;
    }
    s=(Node *)malloc(len);
    s->data=x;
    s->prior=p->prior;
    p->prior->next=s;
    s->next=p;
    p->prior=s;
}

void PrintDLLinkList(DoubleLinkList DL)
{
    Node *p;
    p=DL->next;
    for(;p!=DL;p=p->next)
        printf("%-3d",p->data);
    printf("
");
}

int main()
{
    DoubleLinkList DL;
    InitDLLinkList(&DL);
    CreatDLLinkList(DL);
    PrintDLLinkList(DL);
    
    int x,i;
    printf("Please enter the location you want to insert:
");
    scanf("%d",&i);
    printf("Please enter the values you want to insert:
") ;
    scanf("%d",&x);
    
    InDLLinkList(DL,i,x);
    PrintDLLinkList(DL);
    free(DL);
    return 0;
}

  双向链表的删除

  找到被删除的结点p后,使p的前驱的后继指向p的后继,p的后继的前驱指向p的前驱

#include<stdio.h>
#include<stdlib.h>
#define len sizeof(Node)

typedef struct Node
{
    int data;
    struct Node *prior,*next;
}Node,*DoubleLinkList;

void InitDLLinkList(DoubleLinkList *DL)
{
    *DL=(DoubleLinkList)malloc(len);
    (*DL)->next=NULL;
    (*DL)->prior=NULL;
}

void CreatDLLinkList(DoubleLinkList DL)
{
    Node *p,*s;
    p=DL;
    int x,flag=1;
    printf("Please input data and enter 0 end:
");
    while(flag)
    {
        scanf("%d",&x);
        if(x!=0)
        {
            s=(Node *)malloc(len);
            s->data=x;
            p->next=s;
            s->prior=p;    
            p=s;
        }
        else
        {
            p->next=DL;
            DL->prior=p;
            flag=0;
        }
    }    
}

void DelDLLinkList(DoubleLinkList DL,int i)
{
    Node *p=DL->next;          //从第一个数据节点开始,不是头结点 
    int k=1;
    if(i<=0)
    {
        printf("You enter location illegal:
");
        return;
    }
    while(p!=DL&&k<i)            //p指向被删除的结点 
    {
        p=p->next;
        k++;
    }
    p->prior->next=p->next;      //p的前驱的后继指向p的后继 
    p->next->prior=p->prior;     //p的后继的前驱指向p的前驱 
    free(p);
}

void PrintDLLinkList(DoubleLinkList DL)
{
    Node *p;
    p=DL->next;                    // 
    for(;p!=DL;p=p->next)          //
        printf("%-3d",p->data);
    printf("
");
}

int main()
{
    int i;
    DoubleLinkList DL;
    InitDLLinkList(&DL);
    CreatDLLinkList(DL);
    printf("Please enter the location you want to insert:
");
    scanf("%d",&i);
    DelDLLinkList(DL,i);
    PrintDLLinkList(DL);
    free(DL);
    return 0;
}

 

以上是关于双向链表的建立插入删除的主要内容,如果未能解决你的问题,请参考以下文章

数据结构:链表

c语言 双向链表的简单操作-创建插入删除

线性表--链表基础

线性表--链表基础

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

双向链表的实现