2018-10-02 數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)---雙向鏈表的實(shí)現(xiàn)

2018.10.2 數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)---雙向鏈表的實(shí)現(xiàn)

/*
 * 學(xué)習(xí)時(shí)間:2018-10-2
 * 學(xué)習(xí)內(nèi)容:數(shù)據(jù)結(jié)構(gòu)之尾插法實(shí)現(xiàn)雙向鏈表,以及鏈表的增刪查改
 * 學(xué)習(xí)人:田超
 * QQ:770925351
 * Email:770925351@qq.com
 * 開發(fā)環(huán)境:Ubuntu 16.04 + CLion
 * */
#include <stdio.h>
#include <stdlib.h>

#define TRUE 1
#define FALSE 0
typedef struct DLNode   //定義循環(huán)鏈表結(jié)構(gòu)體
{
    int data;
    struct DLNode *prior;
    struct DLNode *next;
}DLNode;

void createDList(DLNode *&L,int a[],int n)  //創(chuàng)建雙向鏈表
{
    DLNode *s,*r;                           //s用于新建節(jié)點(diǎn),r用于跟蹤L的尾端節(jié)點(diǎn)
    int i;                                  //for循環(huán)臨時(shí)變量
    L=(DLNode*)malloc(sizeof(DLNode));      //開辟循環(huán)鏈表頭結(jié)點(diǎn)空間
    L->prior=NULL;                          //初始化頭結(jié)點(diǎn)前驅(qū)指針
    L->next=NULL;                           //初始化頭結(jié)點(diǎn)后繼指針
    r=L;                                    //初始化r
    for(i=0;i<n;i++)
    {
        s=(DLNode*)malloc(sizeof(DLNode));  //開辟新節(jié)點(diǎn)空間
        s->data=a[i];                       //將數(shù)值賦值給新節(jié)點(diǎn)的數(shù)據(jù)域
        r->next=s;                          //將r指向的后繼變成s
        s->prior=r;                         //將s指向的前趨設(shè)置為r
        r=s;                                //r移位,變成鏈表的最后一個(gè)節(jié)點(diǎn)
    }
    r->next=NULL;                           //此時(shí)r為最后一個(gè)節(jié)點(diǎn),將它的后繼指針變成NULL,創(chuàng)建鏈表結(jié)束
}

void travelNode(DLNode *L)
{
    DLNode *p=L->next;
    while(p!=NULL)
    {
        printf("data=%d\n",p->data);
        p=p->next;
    }
}

DLNode* findNode(DLNode *L,int x)           //在雙向鏈表中查找x元素
{
    DLNode *p=L->next;                      //p為指向鏈表的指針,并初始化指向除頭節(jié)點(diǎn)第一個(gè)節(jié)點(diǎn)
    while(p!=NULL)                          //當(dāng)p不為空時(shí)候,一直循環(huán)
    {
        if(p->data==x)                      //比較值的大小,如果相等,則找到,立即結(jié)束循環(huán)
            break;
        p=p->next;                          //沒有找到,p指向下一個(gè)節(jié)點(diǎn)
    }
        return p;                           //返回p指針,如果找到則會(huì)返回節(jié)點(diǎn)的地址,如果找不到,說明p到了最后一個(gè)節(jié)點(diǎn),最后一個(gè)節(jié)點(diǎn)的next指針是NULL
}

void insertNode_tail(DLNode *L,int x)       //在雙向鏈表中插入x元素,尾插法
{
    DLNode *p,*s;                           //s用來新建節(jié)點(diǎn),p用來尋找當(dāng)前鏈表中最后一個(gè)節(jié)點(diǎn)
    p=L->next;                              //初始化p節(jié)點(diǎn)
    while(p&&p->next!=NULL)                 //循環(huán)找到L的最后一個(gè)節(jié)點(diǎn),并賦值給p,在這里判斷的邏輯是:p不能為空且p的后繼指針不能為空,當(dāng)為空時(shí)候結(jié)束循環(huán),說明p是最后一個(gè)節(jié)點(diǎn)
    {
        p=p->next;
    }
    s=(DLNode*)malloc(sizeof(DLNode));      //新建節(jié)點(diǎn)
    s->data=x;                              //將傳進(jìn)來的數(shù)據(jù)賦值給s
    if(p==NULL)                             //如果此時(shí)鏈表為空,則插入的節(jié)點(diǎn)是第一個(gè)節(jié)點(diǎn)
    {
        s->prior=L;                         //s節(jié)點(diǎn)的前趨指向頭結(jié)點(diǎn)
        s->next=p;                          //s節(jié)點(diǎn)的后繼指向p,也就是NULL
        L->next=s;                          //此時(shí)s作為鏈表的第一個(gè)節(jié)點(diǎn),也就是L->next
    }
    else
    {
        s->prior=p;                         //將s的前趨指針指向p
        s->next=p->next;                    //將s的后繼指針指向原先p的后繼,因?yàn)閜是最后一個(gè)節(jié)點(diǎn),所以是NULL,如果說是中間的節(jié)點(diǎn)的話,就不是NULL
        p->next=s;                          //將p的后繼重新指向s
    }

}

void insertNode_head(DLNode *L,int x)       //在雙向鏈表中插入x元素,頭插法
{
    DLNode *s;                              //s用來新建節(jié)點(diǎn)
    s=(DLNode*)malloc(sizeof(DLNode));      //為s開辟空間
    s->data=x;                              //將數(shù)據(jù)賦值給新建的節(jié)點(diǎn)s的data域
    s->prior=L;                             //將s的前趨指針指向頭結(jié)點(diǎn)
    s->next=L->next;                        //將s的后繼指針指向原先的第一個(gè)節(jié)點(diǎn)
    if(L->next==NULL)                       //如果此時(shí)鏈表為空,那么s節(jié)點(diǎn)將
        L->next=s;
    else
    {
        L->next->prior=s;                   //將原先第一個(gè)節(jié)點(diǎn)的前趨指針指向s
        L->next=s;                          //將頭節(jié)點(diǎn)的next指針指向s
    }

}

int deleteNode(DLNode *L,int x)             //在雙向鏈表中刪除節(jié)點(diǎn)
{
    DLNode *p=L->next;                      //讓p指向除頭節(jié)點(diǎn)外的第一個(gè)節(jié)點(diǎn)
    while(p!=NULL)                          //循環(huán)至最后一個(gè)節(jié)點(diǎn)
    {
        if(p->data==x)                      //如果找到節(jié)點(diǎn)
        {
            if(p->next==NULL)               //如果找到的是最后一個(gè)節(jié)點(diǎn)
            {
                p->prior->next = p->next;   //將p節(jié)點(diǎn)前趨的后繼指針指向NULL
                free(p);                    //釋放空間
            }
            else
            {
                p->prior->next = p->next;   //將p節(jié)點(diǎn)前趨的后繼指針指向p的后繼
                p->next->prior = p->prior;  //將p節(jié)點(diǎn)后繼的前趨指針指向p的前趨
                free(p);                    //釋放空間
            }
            return TRUE;                    //返回真
        }
        p=p->next;                          //沒有找到將p指向下一個(gè)節(jié)點(diǎn)
    }
    return FALSE;                           //循環(huán)結(jié)束,沒有找到,返回假
}

int main()
{
    int a[5]={1,2,3,4,5};
    int n=5;
    DLNode *L;
    createDList(L,a,n);
    travelNode(L);
    printf("\n");
    deleteNode(L,5);
    travelNode(L);
    printf("\n");
    insertNode_tail(L,6);
    travelNode(L);
    printf("\n");
    insertNode_head(L,7);
    travelNode(L);
    printf("\n");
    return 0;
}
?著作權(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)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笙蒙,“玉大人抵屿,你說我怎么就攤上這事⊥蔽唬” “怎么了轧葛?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長艇搀。 經(jī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
  • 文/蒼蘭香墨 我猛地睜開眼士袄,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼悲关!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起娄柳,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤寓辱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赤拒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秫筏,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有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
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至轴脐,卻和暖如春调卑,著一層夾襖步出監(jiān)牢的瞬間抡砂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工恬涧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留注益,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓溯捆,卻偏偏與公主長得像丑搔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子现使,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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