1. 程式人生 > >線性表(四)——迴圈連結串列

線性表(四)——迴圈連結串列

迴圈連結串列

構造原理

迴圈連結串列是指連結串列中最後那個鏈結點的指標域存放指向連結串列最前面那個結點的指標,整個連結串列形成一個環。分為不帶頭結點的迴圈連結串列和帶頭結點的迴圈連結串列,最長使用的是不帶頭結點的(p=list)。
在這裡插入圖片描述

基本操作

1、求迴圈連結串列的長度

int LENGTH( LinkList list ){
    LinkList p=list;
    int n=0;            /* 連結串列的長度置初值0*/
    do{
         p=p->link;
         n++;
   }while( p != list);
   return n; /* 返回連結串列的長度n */
}

2、約瑟夫(JOSEPHU)問題
已知n個人(不妨分別以編號1,2,3,…,n代表)圍坐在一張圓桌周圍,編號為k的人從1開始報數,數到m的那個人出列,他的下一個人又從1開始繼續報數,數到m的那個人出列,…,依此重複下去,直到圓桌周圍的人全部出列。直到圓桌周圍只剩一個人。
在這裡插入圖片描述
需要做的工作:
1、建立一個不帶頭結點的迴圈連結串列;
2、找到第一個出發點;
3、反覆刪除一個鏈結點;

void JOSEPHU( int n, int m, int k ){ 
    LinkList list,p,r;
    int i;
    list=NULL;
    for(i=1;i<=n;i++) { 
        p = (LinkList)malloc(sizeof(LNode));
        p->data=i;
        if (list==NULL) 
            list=p;
        else
            r->link=p;
        r=p;
    }
    p->link=list; 
    /* 至此建立迴圈連結串列步驟完成*/
    p=list;
    for(i=1;i<=k-1;i++) {       /* 找到第一個點,此時p指向第一個出發節點*/
         r=p;
         p=p->link;
    }             
    while(p->link != p) {
        for(i=1;i<=m-1;i++){
            r=p;                         //不多餘,當k!=1但m=1時沒有此句話刪除動作無法進行
            p=p->link;
        }                                    //p指向第m個節點,r指向第m-1個節點
        r->link=p->link;             //刪除第m個節點
        printf(“%3d”,p->data);    //輸出一個節點編號
        free(p);                          //釋放被刪除節點的空間
        p=r->link;                      //p指向新的出發節點
    }
    printf(“\n最後被刪除的節點是%4d”, p->data);      //輸出最後被刪除節點的編號
}