双向循环链表创建、插入、删除操作 《大话数据结构》 c++代码实现

以下是用双向循环链表实现的线性表

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
 
typedef int ElemType;//ElemType这里假设为int,可以根据需要进行更改
typedef int Status;//Status是函数的类型,其值是函数结果状态代码,如OK等
 
typedef struct dulNode//线性表的双向链表存储结构
{
    ElemType data;
    struct dulNode *prior;//直接前驱指针
    struct dulNode *next;//直接后继指针
}DulNode;
 
/*初始化双向循环链表*/
Status InitList(DulNode **L)
{
    *L=(DulNode *)malloc(sizeof(DulNode));
    if(!(*L))
        return ERROR;
 
    (*L)->next=(*L)->prior=*L;
 
    return OK;
}
 
/*初始条件:链式线性表L已存在*/
/**操作结果:返回L中数据元素个数*/
int ListLength(DulNode *L)
{
    int i=0;
    DulNode *p=L->next;
    while(p!=L)
    {
        p=p->next;
        i++;
    }
 
    return i;
}
 
/*初始条件:双向循环链表L已存在,1≤i≤ListLength(L)+1*/
/*操作结果:在L中第i个位置插入新的数据元素e,L的长度加1*/
Status ListInsert(DulNode *L,int i,ElemType e)
{
    int j;
    DulNode *p,*s;//p指向要插入位置的前一个结点,s为新结点
 
    if(i<1)//插入位置不合理
        return ERROR;
 
    p=L;
    j=1;
 
    while(j<i)/*寻找第i个结点的前一个结点*/
    {
        p=p->next;
        j++;
        if(p==L)//未找到
            return ERROR;
    }
 
    s=(DulNode *) malloc(sizeof(DulNode));
    s->data=e;
    s->prior=p;
    s->next=p->next;
    p->next->prior=s;
    p->next=s;
 
    return OK;
}
 
/*初始条件:双向循环链表L已存在/
/*操作结果:输出L的每个数据元素*/
Status ListTraverse(DulNode *L)
{
    DulNode *p=L->next;
    while(p!=L)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
 
    return OK;
}
 
/*初始条件:双向循环链表L已存在。
/*操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(DulNode *L)
{ 
    if(L->next==L && L->prior==L)
        return TRUE;
    else
        return FALSE;
}
 
/*初始条件:双向循环链表L已存在。*/
/*操作结果:将L重置为空表。*/
Status ClearList(DulNode *L)
{
    DulNode *p;//p指向第一个结点
 
    p=L->next;
    while(p!=L)
    {
        p=p->next;
        free(p->prior);
    }
    L->next=L->prior=L;//头结点的两个指针域指向其自己
    
    return OK;
}
 
/*初始条件:双向循环链表L已存在,1≤i≤ListLength(L)*/
/*操作结果:用e返回L中第i个数据元素的值*/
Status GetElem(DulNode *L,int i,ElemType *e)
{
    DulNode *p;
    int j;
 
    if(i<1)//取值位置不合理
        return ERROR;
 
    p=L->next;//p指向第一个结点
    j=1;
    while(p!=L&&j<i)
    {
        p=p->next;
        j++;
    }
 
    if(p==L)//第i个数据元素不存在
        return ERROR;
    *e=p->data;
 
    return OK;
}
 
/*初始条件:双向循环链表L已存在*/
/*操作结果:返回L中第1个与e满足关系的数据元素的位序。*/
/*若这样的数据元素不存在,则返回值为0*/
Status LocateElem(DulNode *L,ElemType e)
{
    int i=0;
    DulNode *p=L->next;
    while(p!=L)
    {
        i++;
        if(p->data==e) /* 找到这样的数据元素 */
                return i;
        p=p->next;
    }
 
    return 0;
}
 
/*初始条件:双向循环链表L已存在,1≤i≤ListLength(L)*/
/*操作结果:删除L的第i个数据元素,并用e返回其值*/
Status ListDelete(DulNode *L,int i,ElemType *e) 
{
    DulNode *p;//p指向第i个结点
    int j;
 
    p=L->next;
    j=1;
 
    if(i<1)//删除位置不合理
        return ERROR;
 
    while(p!=L&&j<i)
    {
        p=p->next;
        j++;
    }
 
    if(p==L)//第i个数据元素不存在
        return ERROR;
    
    *e=p->data;
    p->prior->next=p->next;
    p->next->prior=p->prior;
    free(p);
 
    return OK;
}
 
/*初始条件:双向循环链表L已存在/
/*操作结果:返回L中第一个数据元素值为cur_e的前驱结点的值pre_e*/
Status PriorElem(DulNode *L,ElemType cur_e,ElemType *pre_e)
{
    DulNode *p;
    p=L->next;
    while(p!=L)
    {
        if(p->data==cur_e)//找到数据元素cur_e结点
        {
            if(p->prior==L)//如果该结点是第一个结点
                return ERROR;
 
            *pre_e=p->prior->data;
            return OK;
        }
        p=p->next;
    }
 
    return ERROR;
}
 
/*初始条件:双向循环链表L已存在/
/*操作结果:返回L中第一个数据元素值为cur_e的后继结点的值pre_e*/
Status NextElem(DulNode *L,ElemType cur_e,ElemType *next_e)
{
    DulNode *p;
    p=L->next;
    while(p!=L)
    {
        if(p->data==cur_e)//找到数据元素cur_e结点
        {
            if(p->next==L)//如果该结点是最后一个结点
                return ERROR;
 
            *next_e=p->next->data;
            return OK;
        }
        p=p->next;
    }
 
    return ERROR;
}
 
int main()
{
    DulNode *L;//头指针
 
    int i,j,k;
    ElemType e;
    Status s;
 
    InitList(&L);
    printf("初始化L后:ListLength(L) = %d\n",ListLength(L));    
 
    for(j=1;j<=5;j++)
            i=ListInsert(L,1,j);
    printf("在L的表头依次插入1~5后:L.data = ");
    ListTraverse(L); 
 
    printf("ListLength(L)=%d \n",ListLength(L));
    i=ListEmpty(L);
    printf("L是否空:i = %d(1:是 0:否)\n",i);
 
    i=ClearList(L);
    printf("清空L后:ListLength(L) = %d\n",ListLength(L));
    i=ListEmpty(L);
    printf("L是否空:i = %d(1:是 0:否)\n",i);
 
    for(j=1;j<=10;j++)
            ListInsert(L,j,j);
    printf("在L的表尾依次插入1~10后:L.data = ");
    ListTraverse(L); 
    printf("ListLength(L) = %d \n",ListLength(L));
 
    ListInsert(L,1,0);
    printf("在L的表头插入0后:L.data = ");
    ListTraverse(L); 
    printf("ListLength(L) = %d \n",ListLength(L));
 
    GetElem(L,5,&e);
    printf("第5个元素的值为:%d\n",e);
 
    for(j=3;j<=4;j++)
    {
        k=LocateElem(L,j);
        if(k)
            printf("值为%d的元素的位序为%d\n",j,k);
        else
            printf("没有值为%d的元素\n",j);
    }
 
    k=ListLength(L); //k为表长
    for(j=k+1;j>=k;j--)
    {
        i=ListDelete(L,j,&e); //删除第j个数据
        if(i==ERROR)
            printf("删除第%d个数据失败\n",j);
        else
            printf("删除第%d个的元素值为:%d\n",j,e);
    }
    printf("依次输出L的元素:");
    ListTraverse(L); 
 
    j=5;
    ListDelete(L,j,&e); //删除第5个数据
    printf("删除第%d个的元素值为:%d\n",j,e);
    printf("依次输出L的元素:");
    ListTraverse(L); 
 
    i=ClearList(L);
    printf("\n清空L后:ListLength(L) = %d\n",ListLength(L));
 
    for(j=1;j<=10;j++)
            ListInsert(L,j,j);
    printf("在L的表尾依次插入1~10后:L.data = ");
    ListTraverse(L); 
    printf("ListLength(L) = %d \n",ListLength(L));
 
    printf("\n前驱判断\n");
    for(j=1;j<=10;j++)
    {
        s=PriorElem(L,j,&e);
        if(s==ERROR)
            printf("元素%d没有前驱\n",j);
        else
            printf("元素%d的前驱是%d\n",j,e);
    }
 
    printf("\n后继判断\n");
    for(j=1;j<=10;j++)
    {
        s=NextElem(L,j,&e);
        if(s==ERROR)
            printf("元素%d没有后继\n",j);
        else
            printf("元素%d的后继是%d\n",j,e);
    }
 
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值