學習數(shù)據(jù)結(jié)構(gòu)第一彈 線性表(5)

循環(huán)鏈表與雙向鏈表

循環(huán)鏈表:

循環(huán)鏈表也是一種線性表的鏈式存儲結(jié)構(gòu),其實他和單鏈表很像澜躺,其特點是它是一個環(huán)蝉稳,也就是指單鏈表的最后一個結(jié)點的指針域不為空掘鄙,而是指向頭結(jié)點或是第一個結(jié)點耘戚,這樣整個鏈表就形成了一個環(huán)通铲。循環(huán)鏈表一般可以分為單循環(huán)鏈表和多循環(huán)鏈表,多循環(huán)鏈表也就是將表中的結(jié)點鏈在多個環(huán)上颅夺。

這種方式在單向和雙向鏈表中皆可實現(xiàn)朋截,其轉(zhuǎn)換方法是,選擇從任一結(jié)點開始沿著列表的任一方向直到返回開始的結(jié)點部服。

除此之外,還有一種模擬的循環(huán)鏈表拗慨,就是在訪問最后一結(jié)點之后的時候廓八,手工跳轉(zhuǎn)到第一個結(jié)點赵抢,訪問第一個結(jié)點之前的結(jié)點也一樣剧蹂。通過這樣的方式也可以實現(xiàn)循環(huán)鏈表的功能,在直接運用循環(huán)鏈表比較麻煩或者可能會出現(xiàn)問題的時候可以用烦却。

循環(huán)鏈表的操作:

下面主要講單循環(huán)鏈表宠叼,單循環(huán)鏈表的操作和單鏈表的操作沒什么區(qū)別,只是循環(huán)結(jié)束的條件判斷不再是判斷指針p或p->next是否為空其爵,而是判斷他們是否等于頭結(jié)點冒冬。

有時候,循環(huán)鏈表中會設(shè)置一個指向表尾的尾指針摩渺,這樣對某些操作會很方便

代碼實現(xiàn)

其實絕大部分操作和單鏈表都很相像简烤,這里就不在描述,下面可以講講
兩個單循環(huán)鏈表的合并操作

/*
假設(shè)現(xiàn)在有兩個單循環(huán)鏈表AB摇幻,將其合并的思路如下
A B分別為單循環(huán)鏈表的尾指針
q = B->next;            //q指向B的頭結(jié)點
B->next = A->next;      //B的指針指向A的頭結(jié)點
A->next = q->next;      //A的尾指針指向B的第一個結(jié)點横侦,即B鏈接到A上
A = B;                  //A指向B挥萌,作為合并后鏈表的尾指針
free(q);                //釋放B的頭結(jié)點
                                                        */
LinkList ConnectList(LinkList headA,LinkList headB)
{
    Node *p;
    Node *tailA,*tailB;
    tailA = headA->next;
    tailB = headB->next;
    //分別找到兩個鏈表的尾結(jié)點
    while(tailA->next != headA)     
        tailA = tailA->next;
    while(tailB->next != headB)
        tailB = tailB->next;
    
    p = tailB->next;
    tailB->next = tailA->next;
    tailA->next = p->next;
    tailA = tailB;
    free(p);
    return headA;
}   

雙向鏈表:

在單鏈表中,訪問任一結(jié)點丈咐,如果訪問的是后繼結(jié)點瑞眼,直接通過后繼指針就可以輕松完成此操作(O(1)),如果是訪問其前驅(qū)結(jié)點棵逊,就必須從表頭結(jié)點順鏈查找伤疙,其實時間復雜度為O(n),顯然這樣十分不方便辆影,但如果加多一個指針域呢徒像,這樣無論是前驅(qū)結(jié)點還是后繼結(jié)點訪問起來就比較容易了,這種鏈表就是雙向鏈表蛙讥。

雙向聯(lián)表的描述:

typedef struct dualnode
{
    ElemType data;
    struct dualnode *prior;         //指向前驅(qū)結(jié)點的指針域
    struct dualnode *next;          //指向后繼結(jié)點的指針域
}DNode;
typedef DNode* DLinkList;   

對于帶有頭結(jié)點的雙向鏈表來說逐工,其頭結(jié)點的prior域為NULL假颇,尾結(jié)點的next域為NULL杂瘸,所以如果是一個空的雙向鏈表的話粱檀,兩個指針域都為空。

雙向鏈表轉(zhuǎn)化為循環(huán)鏈表時迫像,雙向循環(huán)鏈表的頭結(jié)點的前驅(qū)指針prior指向表尾結(jié)點劈愚,尾結(jié)點的后繼指針指向頭結(jié)點,所以對于一個空的雙向循環(huán)鏈表闻妓,頭結(jié)點的兩個指針均指向自身菌羽。

雙向鏈表的基本操作:

對于一些向計算表長,獲取元素位置和獲取元素等只涉及一個方向的指針的操作由缆,與單鏈表的操作相同注祖。但是對于插入刪除操作來說比起單鏈表就有較大的差異。

//插入操作
Status ListInsert(DLinkList l,int i,ElemType e)
{
    int k = 1;
    DNode *p,*s;
    p = l->next;
    while(p->next && k<i)
    {
        k++;
        p  = p->next;
    }
    if(k>i || !p)                     //插入位置無效
        return ERROR;
    s = (DNode*)malloc(sizeof(DNode));//為新結(jié)點開辟空間
    s->data = e;
    s->prior = p->prior;              //新結(jié)點的前驅(qū)指針指向p的前驅(qū)結(jié)點
    p->prior->next = s;               //p的前驅(qū)結(jié)點的后繼指針指向新結(jié)點
    s->next = p;                      //新結(jié)點的后繼指針指向p
    p->prior = s;                     //p的前驅(qū)指針指向s
    return OK;
}
//刪除操作
Status DeleteList(DLinkList l,int i,ElemType *e)
{
    int k = 1;
    DNode *p;
    p = l->next;
    while(p->next && k<i)
    {
        p = p->next;
        k++;
    }
    if(!p || k>i)                   //刪除位置無效
        return ERROR;
    *e = p->data;
    p->prior->next = p->next;       //將P的前驅(qū)結(jié)點的后繼指針指向p的后繼結(jié)點
    p->next->prior = p->prior;      //將p的后繼結(jié)點的前驅(qū)指針指向p的前驅(qū)結(jié)點
    free(p);                        //釋放結(jié)點p
    return OK;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末均唉,一起剝皮案震驚了整個濱河市是晨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舔箭,老刑警劉巖署鸡,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異限嫌,居然都是意外死亡,警方通過查閱死者的電腦和手機时捌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門怒医,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奢讨,你說我怎么就攤上這事稚叹。” “怎么了?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵扒袖,是天一觀的道長塞茅。 經(jīng)常有香客問我,道長季率,這世上最難降的妖魔是什么野瘦? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮飒泻,結(jié)果婚禮上鞭光,老公的妹妹穿的比我還像新娘。我一直安慰自己泞遗,他們只是感情好惰许,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著史辙,像睡著了一般汹买。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上聊倔,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天晦毙,我揣著相機與錄音,去河邊找鬼方库。 笑死结序,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的纵潦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼返敬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了寥院?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤凛澎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后估蹄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡臭蚁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年讯赏,在試婚紗的時候發(fā)現(xiàn)自己被綠了冷尉。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡雀哨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出震束,到底是詐尸還是另有隱情,我是刑警寧澤垢村,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站嘉栓,受9級特大地震影響宏榕,放射性物質(zhì)發(fā)生泄漏侵佃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一馋辈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧迈螟,春花似錦、人聲如沸答毫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽消返。三九已至耘拇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惫叛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工挣棕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人洛心。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像词身,于是被迫代替她去往敵國和親厅目。 傳聞我的和親對象是個殘疾皇子法严,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容