6. 循環(huán)雙向鏈表

循環(huán)雙向鏈表是一種更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)類型匹耕,它的節(jié)點(diǎn)包含指向其前一節(jié)點(diǎn)以及下一節(jié)點(diǎn)的指針秧廉。 循環(huán)雙向鏈表在任何節(jié)點(diǎn)中都不包含NULL荧库。 鏈表的最后一個(gè)節(jié)點(diǎn)包含列表的第一個(gè)節(jié)點(diǎn)的地址膛壹。 鏈表的第一個(gè)節(jié)點(diǎn)還包含的前一個(gè)指針是指向最后一個(gè)節(jié)點(diǎn)的地址驾中。

循環(huán)雙向鏈表如下圖所示 -


image

由于循環(huán)雙向鏈表在其結(jié)構(gòu)中包含三個(gè)部分豆巨,因此每個(gè)節(jié)點(diǎn)需要更多空間和更昂貴的基本操作解寝。 但是痊远,循環(huán)雙向鏈表提供了對(duì)指針更方便的操作枚碗,搜索效率提高了兩倍想际。

1. 循環(huán)雙向鏈表的內(nèi)存管理

下圖顯示了為循環(huán)雙向鏈表分配內(nèi)存的方式损趋。 變量head包含鏈表的第一個(gè)元素的地址茫虽,即地址1屎勘,因此鏈表的起始節(jié)點(diǎn)包含數(shù)據(jù)A存儲(chǔ)在地址1中侄柔。因此共啃,鏈表的每個(gè)節(jié)點(diǎn)應(yīng)該具有三個(gè)部分,起始節(jié)點(diǎn)包含最后一個(gè)(也是前一個(gè))節(jié)點(diǎn)的地址暂题,即8和下一個(gè)節(jié)點(diǎn)移剪,即4。鏈表的最后一個(gè)節(jié)點(diǎn)薪者,存儲(chǔ)在地址8并包含數(shù)據(jù)6纵苛,包含鏈表的第一個(gè)節(jié)點(diǎn)的地址,如圖中所示言津,即地址1攻人。在循環(huán)雙向鏈表中,最后一個(gè)節(jié)點(diǎn)由第一個(gè)節(jié)點(diǎn)的地址標(biāo)識(shí)悬槽,該節(jié)點(diǎn)存儲(chǔ)在最后一個(gè)節(jié)點(diǎn)的next中怀吻,因此包含第一個(gè)節(jié)點(diǎn)地址的節(jié)點(diǎn)實(shí)際上是該節(jié)點(diǎn)的最后一個(gè)節(jié)點(diǎn)。

image

2. 循環(huán)雙向鏈表的操作

可以在循環(huán)雙鏈表上執(zhí)行各種操作初婆。循環(huán)雙鏈表的節(jié)點(diǎn)結(jié)構(gòu)類似于雙向鏈表蓬坡。 但是,循環(huán)雙向鏈表上的操作如下表所述磅叛。

編號(hào) 操作 描述
1 在開頭插入節(jié)點(diǎn) 在循環(huán)雙向鏈表的開頭添加節(jié)點(diǎn)屑咳。
2 在末尾插入節(jié)點(diǎn) 在循環(huán)雙向鏈表的末尾添加節(jié)點(diǎn)。
3 刪除開頭節(jié)點(diǎn) 刪除循環(huán)雙向鏈表開頭的節(jié)點(diǎn)弊琴。
4 刪除末尾節(jié)點(diǎn) 刪除循環(huán)雙向鏈表末尾的節(jié)點(diǎn)乔宿。

在循環(huán)雙向鏈表中遍歷和搜索類似于循環(huán)單鏈表中的遍歷和搜索,因此不再說明访雪。

C語(yǔ)言實(shí)現(xiàn)的示例代碼 -

#include<stdio.h>  
#include<stdlib.h>  
struct node
{
    struct node *prev;
    struct node *next;
    int data;
};
struct node *head;
void insertion_beginning();
void insertion_last();
void deletion_beginning();
void deletion_last();
void display();
void search();
void main()
{
    int choice = 0;
    while (choice != 9)
    {
        printf("*********Main Menu*********\n");
        printf("Choose one option from the following list ...\n");
        printf("===============================================\n");
        printf("1.Insert in Beginning\n2.Insert at last\n");
        printf("3.Delete from Beginning\n4.Delete from last\n");
        prinft("5.Search\n6.Show\n7.Exit\n");
        printf("Enter your choice?\n");
        scanf("\n%d", &choice);
        switch (choice)
        {
        case 1:
            insertion_beginning();
            break;
        case 2:
            insertion_last();
            break;
        case 3:
            deletion_beginning();
            break;
        case 4:
            deletion_last();
            break;
        case 5:
            search();
            break;
        case 6:
            display();
            break;
        case 7:
            exit(0);
            break;
        default:
            printf("Please enter valid choice..");
        }
    }
}
void insertion_beginning()
{
    struct node *ptr, *temp;
    int item;
    ptr = (struct node *)malloc(sizeof(struct node));
    if (ptr == NULL)
    {
        printf("OVERFLOW");
    }
    else
    {
        printf("Enter Item value");
        scanf("%d", &item);
        ptr->data = item;
        if (head == NULL)
        {
            head = ptr;
            ptr->next = head;
            ptr->prev = head;
        }
        else
        {
            temp = head;
            while (temp->next != head)
            {
                temp = temp->next;
            }
            temp->next = ptr;
            ptr->prev = temp;
            head->prev = ptr;
            ptr->next = head;
            head = ptr;
        }
        printf("Node inserted\n");
    }

}
void insertion_last()
{
    struct node *ptr, *temp;
    int item;
    ptr = (struct node *) malloc(sizeof(struct node));
    if (ptr == NULL)
    {
        printf("OVERFLOW");
    }
    else
    {
        printf("Enter value");
        scanf("%d", &item);
        ptr->data = item;
        if (head == NULL)
        {
            head = ptr;
            ptr->next = head;
            ptr->prev = head;
        }
        else
        {
            temp = head;
            while (temp->next != head)
            {
                temp = temp->next;
            }
            temp->next = ptr;
            ptr->prev = temp;
            head->prev = ptr;
            ptr->next = head;
        }
    }
    printf("node inserted\n");
}

void deletion_beginning()
{
    struct node *temp;
    if (head == NULL)
    {
        printf("UNDERFLOW");
    }
    else if (head->next == head)
    {
        head = NULL;
        free(head);
        printf("node deleted\n");
    }
    else
    {
        temp = head;
        while (temp->next != head)
        {
            temp = temp->next;
        }
        temp->next = head->next;
        head->next->prev = temp;
        free(head);
        head = temp->next;
    }

}
void deletion_last()
{
    struct node *ptr;
    if (head == NULL)
    {
        printf("UNDERFLOW");
    }
    else if (head->next == head)
    {
        head = NULL;
        free(head);
        printf("node deleted\n");
    }
    else
    {
        ptr = head;
        if (ptr->next != head)
        {
            ptr = ptr->next;
        }
        ptr->prev->next = head;
        head->prev = ptr->prev;
        free(ptr);
        printf("node deleted\n");
    }
}

void display()
{
    struct node *ptr;
    ptr = head;
    if (head == NULL)
    {
        printf("nothing to print");
    }
    else
    {
        printf("printing values ... \n");

        while (ptr->next != head)
        {

            printf("%d\n", ptr->data);
            ptr = ptr->next;
        }
        printf("%d\n", ptr->data);
    }

}

void search()
{
    struct node *ptr;
    int item, i = 0, flag = 1;
    ptr = head;
    if (ptr == NULL)
    {
        printf("Empty List\n");
    }
    else
    {
        printf("Enter item which you want to search?\n");
        scanf("%d", &item);
        if (head->data == item)
        {
            printf("item found at location %d", i + 1);
            flag = 0;
        }
        else
        {
            while (ptr->next != head)
            {
                if (ptr->data == item)
                {
                    printf("item found at location %d ", i + 1);
                    flag = 0;
                    break;
                }
                else
                {
                    flag = 1;
                }
                i++;
                ptr = ptr->next;
            }
        }
        if (flag != 0)
        {
            printf("Item not found\n");
        }
    }

}

執(zhí)行上面示例代碼详瑞,得到以下結(jié)果 -

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
1

Enter Item value123

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
2

Enter value234

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
1

Enter Item value90

Node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
2

Enter value80

node inserted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
3

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
4

node deleted

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
6

 printing values ... 
123

*********Main Menu*********

Choose one option from the following list ...

===============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
5

Enter item which you want to search?
123
item found at location 1
*********Main Menu*********

Choose one option from the following list ...

============================================

1.Insert in Beginning
2.Insert at last
3.Delete from Beginning
4.Delete from last
5.Search
6.Show
7.Exit

Enter your choice?
7
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掂林,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坝橡,更是在濱河造成了極大的恐慌泻帮,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件计寇,死亡現(xiàn)場(chǎng)離奇詭異锣杂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)番宁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門元莫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人蝶押,你說我怎么就攤上這事踱蠢。” “怎么了棋电?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵茎截,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我赶盔,道長(zhǎng)企锌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任于未,我火速辦了婚禮撕攒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烘浦。我一直安慰自己抖坪,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布谎倔。 她就那樣靜靜地躺著柳击,像睡著了一般猿推。 火紅的嫁衣襯著肌膚如雪片习。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天蹬叭,我揣著相機(jī)與錄音藕咏,去河邊找鬼。 笑死秽五,一個(gè)胖子當(dāng)著我的面吹牛孽查,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坦喘,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼盲再,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼西设!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起答朋,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贷揽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后梦碗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禽绪,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年洪规,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了印屁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斩例,死狀恐怖雄人,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情樱拴,我是刑警寧澤柠衍,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站晶乔,受9級(jí)特大地震影響珍坊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜正罢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一阵漏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翻具,春花似錦履怯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至工禾,卻和暖如春运提,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闻葵。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工民泵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人槽畔。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓栈妆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鳞尔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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

  • 1 序 2016年6月25日夜嬉橙,帝都,天下著大雨寥假,拖著行李箱和同學(xué)在校門口照了最后一張合照憎夷,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,096評(píng)論 0 12
  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對(duì)這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算昧旨,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,781評(píng)論 0 13
  • 目錄 1拾给、屬性 2、鏈表和數(shù)組的區(qū)別 2.1兔沃、數(shù)組概述 2.2蒋得、數(shù)組和鏈表優(yōu)缺點(diǎn) 2.3、鏈表和數(shù)組的比較 3乒疏、單...
    我哈啊哈啊哈閱讀 2,804評(píng)論 1 41
  • 自從iPhone8發(fā)布會(huì)結(jié)束后怕吴,各大廣告文案運(yùn)營(yíng)設(shè)計(jì)師已經(jīng)發(fā)完借勢(shì)海報(bào) 全場(chǎng)最佳自然還是杜蕾斯那30萬(wàn)月薪的設(shè)計(jì)師...
    我滴個(gè)天吶欄目閱讀 703評(píng)論 0 0
  • 昨晚以極為亢奮的姿態(tài)吃飯窍侧、洗臉、敷面膜转绷,然后晚上不出所料的又失眠了伟件,真討厭自己這種三分鐘的熱度,莽撞的沒辦法控制的...
    白衣卿卿閱讀 224評(píng)論 0 0