双链表各种基本运算的算法

目录

  1. 初始化双链表
  2. 头插法建立双链表
  3. 尾插法建立双链表
  4. 查找第一个值域为e的元素序号
  5. 判断双链表是否为空
  6. 在双链表第i个位置插入值为e的元素
  7. 在双链表L中删除第i个结点
  8. 输出双链表
  9. 求双链表中第i个元素值
  10. 求双链表的长度
  11. 销毁双链表
  12. 主函数
  13. 双链表的基本运算的算法

  • 初始化双链表

 //初始化线性表
void InitList(DLinkNode *&L)
 {
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     L->next=L->prior=NULL;
 }
  • 头插法建立双链表

//采用头插法建立双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
 {
     DLinkNode *s;
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     //前后指针域置为NULL
     L->prior=L->next=NULL;
     //循环建立数据结点
     for(int i=0;i<n;i++)
     {
         //创建数据结点s
         s=(DLinkNode *)malloc(sizeof(DLinkNode));
         s->data=a[i];
         //将s结点插入到原开始结点之前,头节点之后
         s->next=L->next;
         //若L存在数据结构,修改L->next的前驱指针
         if(L->next!=NULL)
            L->next->prior=s;
         L->next=s;
         s->prior=L;
     }
 }
  • 尾插法建立双链表

//采用尾插法建立双链表
 void CreateListR(DLinkNode *&L,ElemType a[],int n)
 {
     DLinkNode *s,*r;
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     L->prior=L->next=NULL;
     //r始终指向尾节点,开始时指向头结点
     r=L;
     //循环建立数据结点
     for(int i=0;i<n;i++)
     {
         //创建数据结点s
         s=(DLinkNode *)malloc(sizeof(DLinkNode));
         s->data=a[i];
         //将s结点插入到r结点之后
         r->next=s;
         s->prior=r;
         //r指向尾结点
         r=s;
     }
     //尾结点的next置为NULL
         r->next==NULL;
}
  • 查找第一个值域为e的元素序号

//查找第一个值域为e的元素序号
int LocateElem(DLinkNode *L,ElemType e)
{
    int i=1;
    //p指向首结点,i置为1(即首结点的序号为1)
    DLinkNode *p=L->next;
    //查找data值为e的结点,其序号为i
    while(p!=NULL&&p->data!=e)
    {
        i++;
        p=p->next;
    }
    if(p==NULL)
        //不存在值为e的结点,返回0
        return(0);
    else
    //存在值为e的结点,返回逻辑序号
        return(i);
}
  • 判断双链表是否为空

//判断线性表是否为空
int ListEmpty(DLinkNode *L)
{
    return(L->next==NULL);
}
  • 在双链表第i个位置插入值为e的元素

//在双链表L的第i个位置插入值为e的结点
int ListInsert(DLinkNode *&L,int i,ElemType e)
{
    //p指向头结点,j设为0
    int j=0;
    DLinkNode *p=L,*s;
    //i错误时返回false
    if(i<0)
        return false;
    //查找第i-1个结点
    while(j<i-1&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    //未找到第i-1个结点,返回false
    if(p==NULL)
        return false;
    //找到第i-1个结点
    else
    {
        //创建新结点s
        s=(DLinkNode *)malloc(sizeof(DLinkNode));
        s->data=e;
        //在p结点之后插入s结点
        s->next=p->next;
        //若p结点存在后继结点,修改其前驱结点
        if(p->next!=NULL)
            p->next->prior=s;
        s->prior=p;
        p->next=s;
        return true;
    }
}
  • 在双链表L中删除第i个结点

//在双链表L中删除第i个结点
int ListDelete(DLinkNode*&L,int i,ElemType &e)
{
    //p指向头结点,j置为0
    int j=0;
    DLinkNode *p=L,*q;
    //i错误返回false
    if(i<=0)
        return false;
    //查找第i-1个结点
    while(j<i-1&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    //未找到第i-1个结点
    if(p==NULL)
        return false;
    //找到第i-1个结点(由p指向它)
    else
    {
        //q指向第i个结点
        q=p->next;
        //当不存在第i个结点时返回false
        if(q==NULL)
            return false;
            //储存即将删除的结点到e中
        e=q->data;
        //从双链表中删除结点q
        p->next=q->next;
        //若q结点存在后继结点,修改其前驱指针
        if(q->next!=NULL)
            q->next->prior=p;
        free(q);
        return true;
    }
}
  • 输出双链表

//输出线性表
void DispList(DLinkNode *L)
{
    DLinkNode *p=L->next;
    while(p!=NULL)
    {
        printf("%c",p->data);
        p=p->next;
    }
    printf("\n");
}
  • 求双链表中第i个元素值

//求线性表中第i个元素值
int GetElem(DLinkNode*L,int i,ElemType&e)
{
    int j=0;
//p指向头结点,j置为0(即头结点的序号为0)
    DLinkNode*p=L;
//若i错误返回0
    if(i<=0)
        return false;
//找第i个结点p
    while(j<i&&p!=NULL)
    {
        j++;
        p=p->next;
    }
//不存在第i个数据结点,返回false
    if(p==NULL)
        return false;
//存在第i个数据结点,返回true
    else
    {
        e=p->data;
        return true;
    }
}
  • 求双链表的长度

//求双链表长度
int ListLength(DLinkNode*L)
{
    //p指向头结点,i置为0
	int i=0;
	DLinkNode*p=L;
	//找尾结点
	while(p->next!=NULL)
	{
	    //i对应结点p的序号
		i++;
		p=p->next;
	}
	return(i);
}
  • 销毁双链表

//销毁线性表
void DestroyList(DLinkNode*&L)
{
//pre指向结点p的前驱结点
    DLinkNode*pre=L,*p=L->next;
//扫描单链表L
    while(p!=NULL)
    {
//释放pre结点
        free(pre);
//pre、p同步后移一个结点
        pre=p;
        p=pre->next;
    }
//循环结束时p为NULL,pre指向尾结点,释放它
    free(pre);
}
  • 主函数

int main()
{
    int i,n=10;
    DLinkNode *L;
    ElemType e,a[10];
    printf("请输入10个字符:\n");
    for(i=0;i<n;i++)
    {
        scanf("%c",&a[i]);
    }
    //调用InitList()初始化线性表
    printf("<1>初始化双链表\n");
    InitList(L);
    printf("<2>初始化双链表成功!\n");
    //调用DreateListF()头插法建立双链表
    printf("<3>用头插法创建双链表:\n");
    CreateListF(L,a,n);
    //调用DispList()输出双链表
    DispList(L);
    //调用DreateListR()尾插法建立双链表
    printf("<4>用尾插法创建双链表:\n");
    CreateListR(L,a,n);
    //调用DispList()输出双链表
    DispList(L);
    //用ListEmpty()判断双链表是否为空
    printf("<5>该双链表为%s\n",ListEmpty(L)?"空":"非空");
    //调用LocateElem()查找第一个值域为e的元素序号
    printf("<6>在双链表中第一个元素值为o的元素序号为:%c\n",  LocateElem(L,'o'));
    //调用ListInsert()插入元素值
    printf("<7>在双链表第3个元素中插入s:\n");
    ListInsert(L,3,'s');
//调用DispList()输出双链表
    DispList(L);
    //调用ListDelete()删除双链表中第6个元素
    printf("<8>删除双链表中第6个元素\n");
    ListDelete(L,6,e);
//调用DispList()输出双链表
    DispList(L);
    //调用ListLength()求线性表长度
    printf("<9>该线性表的长度为%d\n",ListLength(L));
    //调用GetElem()查找线性表中第i个元素值
    printf("<10>线性表中第5个元素值为:%c\n",GetElem(L,5,e));
    //调用DispList()输出双链表
    DispList(L);
    //调用DestroyList()销毁线性表
    printf("<11>销毁线性表:\n");
    DestroyList(L);
    printf("<12>销毁成功!");
}
  • 双链表的基本运算的算法

 #include<stdio.h>
 #include<malloc.h>
 //定义语句类型
 typedef char ElemType;
 //声明DLinkNode节点类型
 typedef struct DNode
 {
     //存放元素值
     ElemType data;
     //指向前驱结点
     struct DNode *prior;
     //指向后驱结点
     struct DNode *next;
 }DLinkNode;       //双链表的结点类型


 //初始化线性表
void InitList(DLinkNode *&L)
 {
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     L->next=L->prior=NULL;
 }


 //采用头插法建立双链表
void CreateListF(DLinkNode *&L,ElemType a[],int n)
 {
     DLinkNode *s;
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     //前后指针域置为NULL
     L->prior=L->next=NULL;
     //循环建立数据结点
     for(int i=0;i<n;i++)
     {
         //创建数据结点s
         s=(DLinkNode *)malloc(sizeof(DLinkNode));
         s->data=a[i];
         //将s结点插入到原开始结点之前,头节点之后
         s->next=L->next;
         //若L存在数据结构,修改L->next的前驱指针
         if(L->next!=NULL)
            L->next->prior=s;
         L->next=s;
         s->prior=L;
     }
 }


 //采用尾插法建立双链表
 void CreateListR(DLinkNode *&L,ElemType a[],int n)
 {
     DLinkNode *s,*r;
     //创建头结点
     L=(DLinkNode *)malloc(sizeof(DLinkNode));
     L->prior=L->next=NULL;
     //r始终指向尾节点,开始时指向头结点
     r=L;
     //循环建立数据结点
     for(int i=0;i<n;i++)
     {
         //创建数据结点s
         s=(DLinkNode *)malloc(sizeof(DLinkNode));
         s->data=a[i];
         //将s结点插入到r结点之后
         r->next=s;
         s->prior=r;
         //r指向尾结点
         r=s;
     }
     //尾结点的next置为NULL
         r->next==NULL;
}

//查找第一个值域为e的元素序号
int LocateElem(DLinkNode *L,ElemType e)
{
    int i=1;
    //p指向首结点,i置为1(即首结点的序号为1)
    DLinkNode *p=L->next;
    //查找data值为e的结点,其序号为i
    while(p!=NULL&&p->data!=e)
    {
        i++;
        p=p->next;
    }
    if(p==NULL)
        //不存在值为e的结点,返回0
        return(0);
    else
    //存在值为e的结点,返回逻辑序号
        return(i);
}

//判断线性表是否为空
int ListEmpty(DLinkNode *L)
{
    return(L->next==NULL);
}


//在双链表L的第i个位置插入值为e的结点
int ListInsert(DLinkNode *&L,int i,ElemType e)
{
    //p指向头结点,j设为0
    int j=0;
    DLinkNode *p=L,*s;
    //i错误时返回false
    if(i<0)
        return false;
    //查找第i-1个结点
    while(j<i-1&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    //未找到第i-1个结点,返回false
    if(p==NULL)
        return false;
    //找到第i-1个结点
    else
    {
        //创建新结点s
        s=(DLinkNode *)malloc(sizeof(DLinkNode));
        s->data=e;
        //在p结点之后插入s结点
        s->next=p->next;
        //若p结点存在后继结点,修改其前驱结点
        if(p->next!=NULL)
            p->next->prior=s;
        s->prior=p;
        p->next=s;
        return true;
    }
}


//在双链表L中删除第i个结点
int ListDelete(DLinkNode*&L,int i,ElemType &e)
{
    //p指向头结点,j置为0
    int j=0;
    DLinkNode *p=L,*q;
    //i错误返回false
    if(i<=0)
        return false;
    //查找第i-1个结点
    while(j<i-1&&p!=NULL)
    {
        j++;
        p=p->next;
    }
    //未找到第i-1个结点
    if(p==NULL)
        return false;
    //找到第i-1个结点(由p指向它)
    else
    {
        //q指向第i个结点
        q=p->next;
        //当不存在第i个结点时返回false
        if(q==NULL)
            return false;
            //储存即将删除的结点到e中
        e=q->data;
        //从双链表中删除结点q
        p->next=q->next;
        //若q结点存在后继结点,修改其前驱指针
        if(q->next!=NULL)
            q->next->prior=p;
        free(q);
        return true;
    }
}


//输出线性表
void DispList(DLinkNode *L)
{
    DLinkNode *p=L->next;
    while(p!=NULL)
    {
        printf("%c",p->data);
        p=p->next;
    }
    printf("\n");
}


//求线性表中第i个元素值
int GetElem(DLinkNode*L,int i,ElemType&e)
{
    int j=0;
//p指向头结点,j置为0(即头结点的序号为0)
    DLinkNode*p=L;
//若i错误返回0
    if(i<=0)
        return false;
//找第i个结点p
    while(j<i&&p!=NULL)
    {
        j++;
        p=p->next;
    }
//不存在第i个数据结点,返回false
    if(p==NULL)
        return false;
//存在第i个数据结点,返回true
    else
    {
        e=p->data;
        return true;
    }
}


//求单链表长度
int ListLength(DLinkNode*L)
{
    //p指向头结点,i置为0
	int i=0;
	DLinkNode*p=L;
	//找尾结点
	while(p->next!=NULL)
	{
	    //i对应结点p的序号
		i++;
		p=p->next;
	}
	return(i);
}


//销毁线性表
void DestroyList(DLinkNode*&L)
{
//pre指向结点p的前驱结点
    DLinkNode*pre=L,*p=L->next;
//扫描单链表L
    while(p!=NULL)
    {
//释放pre结点
        free(pre);
//pre、p同步后移一个结点
        pre=p;
        p=pre->next;
    }
//循环结束时p为NULL,pre指向尾结点,释放它
    free(pre);
}


int main()
{
    int i,n=10;
    DLinkNode *L;
    ElemType e,a[10];
    printf("请输入10个字符:\n");
    for(i=0;i<n;i++)
    {
        scanf("%c",&a[i]);
    }
    //调用InitList()初始化线性表
    printf("<1>初始化双链表\n");
    InitList(L);
    printf("<2>初始化双链表成功!\n");
    //调用DreateListF()头插法建立双链表
    printf("<3>用头插法创建双链表:\n");
    CreateListF(L,a,n);
    //调用DispList()输出双链表
    DispList(L);
    //调用DreateListR()尾插法建立双链表
    printf("<4>用尾插法创建双链表:\n");
    CreateListR(L,a,n);
    //调用DispList()输出双链表
    DispList(L);
    //用ListEmpty()判断双链表是否为空
    printf("<5>该双链表为%s\n",ListEmpty(L)?"空":"非空");
    //调用LocateElem()查找第一个值域为e的元素序号
    printf("<6>在双链表中第一个元素值为o的元素序号为:%c\n",  LocateElem(L,'o'));
    //调用ListInsert()插入元素值
    printf("<7>在双链表第3个元素中插入s:\n");
    ListInsert(L,3,'s');
//调用DispList()输出双链表
    DispList(L);
    //调用ListDelete()删除双链表中第6个元素
    printf("<8>删除双链表中第6个元素\n");
    ListDelete(L,6,e);
//调用DispList()输出双链表
    DispList(L);
    //调用ListLength()求线性表长度
    printf("<9>该线性表的长度为%d\n",ListLength(L));
    //调用GetElem()查找线性表中第i个元素值
    printf("<10>线性表中第5个元素值为:%c\n",GetElem(L,5,e));
    //调用DispList()输出双链表
    DispList(L);
    //调用DestroyList()销毁线性表
    printf("<11>销毁线性表:\n");
    DestroyList(L);
    printf("<12>销毁成功!");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值