(四)循环链表
    单链的循环链表结点的存储结构和单链的存储结构相同。所不同的是:最后一个结点的next指针指向头结点,而不是null。
   尾指针:设立一个指向最后一个结点的指针,作为单链表的名字。
  
结构图:
 
第一部分 线性表的链式存储(四)--单循环链表_数据结构
 
基本操作:
 
/*构造一个单循环链表*/
/*将单循环链表L重置为空链表*/
/*销毁单循环列表L*/
/*若单循环链表L是空表,返回TRUE,否则返回FALSE*/
/*返回单循环链表L中的数据元素个数*/
/*用e返回单循环链表L中的第i个元素的值*/
/*返回单循环列表L中第1个与e满足关系compare()的数据元素的位序*/
/*若cur_e是单循环链表L的数据元素,且不是第一个,则用pre_e返回它的前驱,成功返回ok,否则error*/
/*若cur_e是单循环链表L的数据元素,且不是最后一个,则用next_e返回它的后继,成功返回ok,否则error*/
/*在L中第i个元素之前插入新的数据元素e*/
/*删除单循环链表L中第i个元素,用e返回其值*/
/*依次对单循环链表L中的每一个元素调用函数visit()*/
 
/*构造一个单循环链表*/
void InitList(pLinkList L)
{
    L=(pLinkList)malloc(sizeof(LinkList));
    if(!L)
        exit(OVERFLOW);
    L->next = L;
//头结点的指针指向头结点

}

/*将单循环链表L重置为空链表*/
void ClearList(pLinkList L)
{
    pLinkList p,q;
    L = L->next;
//L指向头结点

    p = L->next;
//p指向第一个结点

    while(p != L)
    {
        q = p->next;
        free(p);
        p = q;
    }
    L->next = L;
//头结点指向自身

}

/*销毁单循环列表L*/
void DestroyList(pLinkList L)
{
    ClearList(L);
    free(L);
    L = NULL;
}

/*若单循环链表L是空表,返回TRUE,否则返回FALSE*/
Status ListEmpty(pLinkList L)
{
    if(L->next == L)
        return TRUE;
    else
        return FALSE;
}

/*返回单循环链表L中的数据元素个数*/
int ListLength(pLinkList L)
{
    int i=0;
    pLinkList p = L->next;
    while(p != L)
//未到表尾

    {
        i++;
        p = p->next;
    }
    return i;
}

/*用e返回单循环链表L中的第i个元素的值*/
Status GetElem(pLinkList L,int i,elemtype *e)
{
    int j = 1;
    pLinkList p = L->next->next;
    if(i<1 || i>ListLength(L))
        return ERROR;
    while(j<i)
    {
        j++;
        p = p->next;
    }
    *e = p->data;
    return OK;
}

/*返回单循环列表L中第1个与e满足关系compare()的数据元素的位序*/
int LocateElem(pLinkList L,elemtype e,Status(*compare)(elemtype,elemtype))
{
    int i = 0;
    pLinkList p = L->next->next;
//p指向第一个元素

    while(p != L->next)
//p未指向头结点

    {
        i++;
        if(compare(p->data,e))
            return i;
        p = p->next;
    }
    return 0;
}

/*若cur_e是单循环链表L的数据元素,且不是第一个,则用pre_e返回它的前驱,成功返回ok,否则error*/
Status PriorElem(pLinkList L,elemtype cur_e,elemtype * pre_e)
{
    pLinkList p=L->next->next;
//p指向第一个结点

    while(p != L)
//p未到表尾

    {
        if(p->next->data == cur_e)
        {
            *pre_e = p->data;
            return OK;
        }
        p = p->next;
    }
    return ERROR;
}

/*若cur_e是单循环链表L的数据元素,且不是最后一个,则用next_e返回它的后继,成功返回ok,否则error*/
Status NextElemtype(pLinkList L,elemtype cur_e,elemtype * next_e)
{
    pLinkList p = L->next->next;
    while(p != L)
    {
        if(p->data == cur_e)
        {
            *next_e = p->next->data;
            return OK;
        }
        p = p->next;
    }
    return ERROR;
}

/*在L中第i个元素之前插入新的数据元素e*/
Status ListInsert(pLinkList L,int i,elemtype e)
{
    int j = 0;
    pLinkList s,p=L->next;
    if(i<1 || i>ListLength(L))
        return ERROR;
    while(j<i-1)
//p指向第i-1个结点

    {
        j++;
        p = p->next;
    }
    s = (pLinkList)malloc(sizeof(LinkList));
    s->data = e;
    s->next = p->next;
    p->next = s;
    if(L == p)
//若插在表尾

        L = s;
    return OK;
}

/*删除单循环链表L中第i个元素,用e返回其值*/
Status ListDelete(pLinkList L,int i,elemtype *e)
{
    int j = 0;
    pLinkList q,p=L->next;
    if(i<1 || i>ListLength(L))
        return ERROR;
    while(j<i-1)
//p指向第i-1个结点

    {
        j++;
        p = p->next;
    }
    q = p->next;
//q指向要删除的结点

    *e = q->data;
    p->next = q->next;
    if(L == q)
//若删除的是最后一个结点

        L = p;
    free(q);
    return OK;
}

/*依次对单循环链表L中的每一个元素调用函数visit()*/
void ListTraverse(pLinkList L,void(*visit)(elemtype))
{
    pLinkList p = L->next->next;
//p指向第一个元素

    while(p != L->next)
    {
        visit(p->data);
        p = p->next;
    }
}