带头结点的双向循环链表的表示和实现

线性表的双向链表存储结构

typedef struct DuLNode
{
    ElemType data;
    DuLNode *prior, *next;
}DuLNode, *DuLinkList;

带有头结点的双向循环链表的14个基本操作

void InitList(DuLinkList &L){
    L = (DuLinkList)malloc(sizeof(DuLNode));
    if (!L)exit(OVERFLOW);
    L->next = L->prior = L;
}

void ClearList(DuLinkList &L){
    DuLinkList p = L->next;//p指向第1个结点
    while (p != L){//p未指向头结点
        p = p->next;//p指向下一个结点
        free(p->prior);//释放p的前驱结点
    }
    L->next = L->prior = L;//头结点的两个指针域均指向自身
}

void DestroyList(DuLinkList &L){
    ClearList(L);
    free(L);
    L = NULL;
}

Status ListEmpty(DuLinkList L){
    if (L->next == L && L->prior == L)return TRUE;
    else return FALSE;
}

int ListLength(DuLinkList L){
    DuLinkList p = L->next;//p指向第1个结点
    int i = 0;
    while (p != L)//p未指向头结点
    {           
        i++;//计数器+1
        p = p->next;//p指向下一个结点
    }
    return i;
}

Status GetElem(DuLinkList L, int i, ElemType &e){
    int j = 1;//初始化,j为计数器,初值为1
    DuLinkList p = L->next;//p指向第1个结点
    while (p != L && j < i)//顺时针向后查找,直到p指向第i个元素或p指向头结点
    {
        j++;
        p = p->next;
    }
    if (p == L || j > i)return ERROR;//第i个元素不存在
    e = p->data;
    return OK;
}

int LocateElem(DuLinkList L, ElemType e, Status(*compare)(ElemType, ElemType)){
    int i = 0;//计数器初值为0
    DuLinkList p = L->next;//p指向第1个元素
    while (p!=L)//p未指向头结点
    {
        i++;
        if (compare(p->data, e))//找到这样的数据元素
            return i;//返回其位序
        p = p->next;//p指向下一个结点
    }
    return 0;//满足关系的数据元素不存在
}

Status PriorElem(DuLinkList L, ElemType cur_e, ElemType &pre_e){
    DuLinkList q, p = L->next->next;//p指向第2个元素
    while (p != L){//p未指向头结点
        if (p->data == cur_e){//p指向值为cur_e的结点
            pre_e = p->prior->data;//将p的前驱结点的值赋给pre_e
            return OK;
        }
        p = p->next;//q指向p的后继
    }
    return ERROR;
}

Status NextElem(DuLinkList L, ElemType cur_e, ElemType &next_e){
    DuLinkList p = L->next->next;//p指向第2个元素
    while (p!=L){//p未到表尾
        if (p->prior->data == cur_e){//p所指结点的值为cur_e
            next_e = p->data;//将p所指结点的后继结点的值赋给next_e
            return OK;
        }
        p = p->next;//p指向下一个结点
    }
    return ERROR;
}

DuLinkList GetElemP(DuLinkList L, int i){
    int j;
    DuLinkList p = L;//p指向头结点
    if (i < 0 || i < ListLength(L)) return NULL;
    for (j = 1; j <= i; j++)//p指向第i个结点
        p = p->next;//p指向下一个结点
    return p;
}

Status ListInsert(DuLinkList L, int i, ElemType e){
    DuLinkList s, p;
    if (i <= 1 || i > ListLength(L) + 1) return ERROR;
    p = GetElemP(L, i - 1);//在L中确定第i个结点前驱的位置指针p
    if (!p) return ERROR;//p=NULL,即第i个结点的前驱不存在(设头结点为第1个结点的前驱)
    s = (DuLinkList)malloc(sizeof(DuLNode));
    if (!s) return ERROR;//生成新结点失败返回ERROR
    s->data = e;//将e赋给新结点
    s->prior = p;//新结点的前驱为第i-1个结点
    s->next = p->next;//新结点的后继为第i个结点
    p->next->prior = s;//第i-1个结点的后继指向新结点
    p->next = s;//第i-1个结点的后继指向新结点
    return OK;
}

Status ListDelete(DuLinkList L, int i, ElemType &e){
    DuLinkList p;
    if (i < 1) return ERROR;//删除失败
    p = GetElemP(L, i);
    if(!p) return ERROR;//p=NULL,即第i个元素不存在
    e = p->data;//将第i个元素的值赋给e
    p->prior->next = p->next;//第i-1个结点的后继指向原第i+1个结点
    p->next->prior = p->prior;//原第i+1个结点的前驱指向第i-1个结点
    free(p);
    return OK;
}

void ListTraverse(DuLinkList L, void(*visit)(ElemType&)){
    DuLinkList p = L->next;//p指向首元结点
    while (p != L)//p不指向头结点
    {
        visit(p->data);
        p = p->next;
    }
    printf("\n");
}

void ListTraverseBack(DuLinkList L, void(*visit)(ElemType&)){
    DuLinkList p = L->prior;//p指向首元结点
    while (p != L)//p不指向头结点
    {
        visit(p->data);
        p = p->prior;
    }
    printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值