1. 程式人生 > >迴圈連結串列基礎

迴圈連結串列基礎

迴圈連結串列

將單鏈表中終端結點的指標段由空指標改為指向頭結點,就使整個單鏈表形成了一個環,這種頭尾相連的單鏈表簡稱迴圈連結串列

這樣迴圈連結串列就解決了一個問題:如何從一個結點出發,訪問到連結串列的全部結點。

為了使空連結串列和非空連結串列處理一致,我們通常設一個頭結點,當然,並不是說迴圈連結串列一定要有頭結點。

其實迴圈連結串列和單鏈表的主要差異就在於迴圈的判斷條件上,原來是判斷p->next是否為空,現在則是判斷其不等於頭結點,則迴圈未結束。

迴圈連結串列的定義

與普通的單鏈表並無二致,只是將尾指標連結到頭結點上,而非之前的NULL,而指標域我們存的不再是頭指標,而是尾指標。

typedef struct LNode {
    ElemType data; //資料域
    struct LNode *next; //指標域,存的不再是頭指標,而是尾指標
}LNode, *LinkList;

迴圈連結串列的初始化

尾插法,每次都要讓尾指標指向頭結點,最後入我們讓連結串列的頭結點裡面存的是尾指標即可。

void InitList(LinkList &L, int n)
{
    L = (LNode*)malloc(sizeof(LNode));
    if(!L) exit(0);
    L->next = L; //初始化頭結點,尾指標指向頭結點
    LNode *p, *tail = L;
    for(int i = 1; i <= n; ++i) {
        p = (LNode*)malloc(sizeof(LNode));
        if(!p) exit(0);
        p->data = i;
        tail->next = p;
        p->next = L;
        tail = p;
    }
    L = p; //將尾指標賦值給指標域
}

迴圈連結串列的合併

由於我們儲存了尾指標,所以合併兩個連結串列變得非常的簡單,下面我們將A連結串列連線到B連結串列上。

void ConnectList(LinkList &rearA, LinkList &rearB) //將A連結串列連線到B連結串列上
{
    LNode *p, *q;
    p = rearA->next;   //儲存A的頭結點
    rearA->next = rearB->next->next; //將本是指向B的第一個結點(不是頭結點),賦值給rearA->next
    q = rearB->next; 
    rearB->next = p;  //將原A表的頭結點賦值給rearB->next
    free(q);  //釋放q
}

迴圈連結串列的遍歷

因為我們的頭結點裡面儲存的是尾指標,所以我們需要使用L->next->next來得到第一個結點的位置。

void traverse(LinkList L)
{
    LNode *p = L->next->next;
    while(p != L->next) {
        printf("%d ", p->data);
        p = p->next;
    }
    puts("");
}