雙鏈表也是線性表的一種,它的全稱是:線性雙向鏈接表,它有以下特點:
在每個節點中除包含有數值域外,設置有兩個指針域,分別用以指向其前驅節點和後繼節點。
既可以依次向後訪問每一個節點,也可以依次向前訪問每一個節點。
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