第一部分 線性表的鏈式存儲(四)--單循環鏈表

(四)循環鏈表
    單鏈的循環鏈表結點的存儲結構和單鏈的存儲結構相同。所不同的是:最後一個結點的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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章