#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
typedef struct {
int id;
}Elemtype;
typedef struct st{
Elemtype data;
struct st *prior,*next;
}DNode,*DLinkList;
bool InitDLinkList(DLinkList *L);
bool InsertDLinkList(DNode *p,DNode *s);
bool DeleteNode(DNode *p);
void DestoryList(DLinkList *L);
void skimDLinkList(DLinkList *L,DNode *q);
int main(){
Elemtype a={1},b={2},c={3};
DNode *d=(DNode *)malloc(sizeof(DNode)),*e=(DNode *)malloc(sizeof(DNode)),*f=(DNode *)malloc(sizeof(DNode));
d->data=a;
e->data=b;
f->data=c;
DLinkList *L= (DLinkList *) malloc(sizeof(DLinkList));
*L = (DNode *) malloc(sizeof(DNode *));
InitDLinkList(L);
InsertDLinkList(*L, d);
InsertDLinkList(*L,e);
DeleteNode(e);
InsertDLinkList(d,f);
DeleteNode(f);
InsertDLinkList(*L,e);
DestoryList(L);
return 0;
}
bool InitDLinkList(DLinkList *L){
/*下面两行代码并不能初始化,因为传进函数之后,只有链表指针成功初始化了。而指针的指针并没有成功的初始化*/
// L = (DLinkList *) malloc(sizeof(DLinkList));//L是指针的指针,如果指针没有指向一个已有的变量,那么指针指向的地方必须要malloc,否则会发生指针乱指的情况
// *L = (DNode *) malloc(sizeof(DNode *));//L是指针的指针,因此*L也是一个指针,指向的地方也要malloc
if (*L == NULL)//内存不足,分配失败
return false;
(*L)->next=NULL;
(*L)->prior=NULL;
return true;
}
//在p结点之后插入s结点
bool InsertDLinkList(DNode *p,DNode *s){//p<->s<->q 分别修改p,s,q;
if (p==NULL || s==NULL)//防止空指针错误
return false;
if (p->next==NULL){//如果p的下一个为空的话,执行以下语句
s->next=p->next;
p->next=s;
s->prior=p;
return true;
}
/*如果p的下一个为空的话,下面代码会发生空指针错误*/
DNode *q=p->next;
s->next = q;
s->prior = p;
p->next = s;
q->prior = s;
return true;
}
//删除p结点
bool DeleteNode(DNode *p){//修改p前面和后面结点就可以了
/*下面两个if是防止空指针用的*/
if (p==NULL)
return false;
if (p->next==NULL){//p是最后一个结点,只需要修改前面那个就行了
p->prior->next=NULL;
free(p);
return true;
}
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);//释放p的空间,这个很重要,在大型项目里面如果不释放会使得内存不足
return true;
}
//销毁整个链表
void DestoryList(DLinkList *L){
while ((*L)->next!=NULL){
DeleteNode((*L)->next);//循环删除L后面的那个结点
}
free(*L);//最后free L
L=NULL;
}
//遍历整个链表
void skimDLinkList(DLinkList *L,DNode *q){
DNode *p=*L;
while (p!=NULL){//后向遍历
p=p->next;
}
while (q->next!=NULL){//q是最后一个结点,这是前向遍历,跳过头结点
q = q->next;
}
}