線性表——雙鏈表

雙鏈表也是線性表的一種,它的全稱是:線性雙向鏈接表,它有以下特點:
在每個節點中除包含有數值域外,設置有兩個指針域,分別用以指向其前驅節點和後繼節點。
既可以依次向後訪問每一個節點,也可以依次向前訪問每一個節點。
這裏寫圖片描述

dlinklist.h如下:

#include <stdio.h>
#include <malloc.h>


typedef int ElemType;
typedef struct Node{
    ElemType data;
    struct Node * prior;
    struct Node * next;
}DLinkList;

DLinkList.cpp如下:

#include "dlinklist.h"
#include <stddef.h>
void headInit(DLinkList * &dll,ElemType arr[], int n);
void printDoubleLinkList(DLinkList * dll);
void tailInit(DLinkList * &dll,ElemType arr[], int n);
bool insertElement(DLinkList *&dll, int pos, ElemType e);
bool deleteElement(DLinkList *&dll, int pos, ElemType &e);
int main() {
    DLinkList * dll;
    ElemType arr[] = {1,2,3,4,5};
    headInit(dll,arr,5);
    printf("頭插法:\t");
    printDoubleLinkList(dll);

    tailInit(dll,arr,5);
    printf("尾插法:\t");
    printDoubleLinkList(dll);

    insertElement(dll,3,6);
    printf("在第3個位置上插入6之後:\t");
    printDoubleLinkList(dll);

    ElemType e;
    deleteElement(dll,3,e);
    printf("刪除第3個元素之後:\t");
    printDoubleLinkList(dll);
}

//頭插法
void headInit(DLinkList * &dll,ElemType arr[], int n){
    int i;
    dll = (DLinkList *) malloc(sizeof(DLinkList));
    //頭節點兩個指針爲NULL
    dll->next = dll->prior = NULL;
    DLinkList * node;
    for(i = 0; i<n; i++){
        node = (DLinkList *) malloc(sizeof(DLinkList));
        node->data = arr[i];
        /*
         *插入,畫圖,依次賦值node->next,node->prior,dll->next(dll->prior永遠爲null)
         *可以發現除了第一次插入,以後插入的節點都要設置dll->next->prior = node
         */
        node->next = dll->next;
        if(dll->next != NULL){
            dll->next->prior = node;
        }
        node->prior = dll;
        dll->next = node;
    }
}

//尾插法
void tailInit(DLinkList * &dll,ElemType arr[], int n){
    int i;
    dll = (DLinkList *) malloc(sizeof(DLinkList));
    //頭節點兩個指針爲NULL
    dll->next = dll->prior = NULL;
    DLinkList * node, *r;
    r = dll;
    for (i = 0; i < n; ++i) {
        node = (DLinkList *) malloc(sizeof(DLinkList));
        node->data = arr[i];
        //尾插,畫圖很簡單
        node->prior = r;
        r->next = node;
        r=node;
    }
    r=NULL;
}

//插入節點,找出前一個節點
bool insertElement(DLinkList *&dll, int pos, ElemType e){
    int i = 0;
    DLinkList *p = dll, *node;
    while(i<pos-1 && p!=NULL){
        p = p->next;
        i++;
    }
    if(p==NULL){
        printf("插入的位置不合法");
        return false;
    }else{
        //分配節點
        node = (DLinkList *)malloc(sizeof(DLinkList));
        node->data = e;
        node->next = p->next;
        node->prior = p;
        if(p->next != NULL){
            p->next->prior = node;
        }
        p->next = node;
        return true;
    }
}

bool deleteElement(DLinkList *&dll, int pos, ElemType &e){
    int i = 0;
    DLinkList *p = dll, *node;
    while(i<pos-1 && p!=NULL){
        p = p->next;
        i++;
    }
    if(p==NULL){
        return false;
    }else{
        node = p->next;
        if(node == NULL){//如果p是尾節點,要刪除的是尾節點的下一個節點,錯誤
            return false;
        }
        e = node->data;
        p->next = node->next;
        if(p->next != NULL){ //此時p->next已經改變,如果node->next爲NULL.NULL不需要設置prior
            node->next->prior = p;
        }
        free(node);
        return true;
    }

}
void printDoubleLinkList(DLinkList * dll){
    //不需要輸出頭節點的data
    DLinkList *p = dll->next;
    while(p != NULL){
        printf("%d\t",p->data);
        p = p->next;
    }
    printf("\n");
}

輸出結果爲:

頭插法:    5   4   3   2   1   
尾插法:    1   2   3   4   5   
在第3個位置上插入6之後:   1   2   6   3   4   5   
刪除第3個元素之後:  1   2   3   4   5   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章