双链表
typedef struct DNode{ //定义双链表
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
DNode 、 *DLinkList 两者是等价的
初始化(带头节点)
typedef struct DNode{ //定义双链表
ElemType data;
struct DNode *prior,*next;
}DNode,*DLinkList;
//初始化双链表
bool InitDLinkList(DLinkList &L){
L = (DNode*)malloc(sizeof(DNode));
if(L == NULL){
return false; //内存不足分配失败
}
L->prior = NULL; //头结点的prior永远指向NULL
L->next = NULL; //头结点之后暂时还没有结点
return true;
}
void testDLinkList(){ //判断双链表是否为空(带头节点)
//初始化双链表
DLinkList L;
InitDLinkList(L);
}
//判断双链表是否为空(带头节点)
bool Empty(DLinkList L){
if(L->next == NULL){
return true;
}else{
return false;
}
}
双链表的插入
过程要注意多画图
//在p结点之后插入s结点
bool InsertNextDNode(DNode *p,DNode *s){
if(p == NULL||s == NULL){
return false;
}
s->next = p->next; // 将结点*s插入到结点*p之后
if(p->next != NULL){ //如果p结点有后继结点
p->next->prior = s;
}
s->prior = p;
p->next = s;
return true;
}
修改指针的时要注意顺序
如果按位序进行插入时,可以找到指定位序的前驱结点,在此结点之后用上述方法插入新结点。
双链表的删除
//删除p的后继节点
bool DeleteNextDNode(DNode *p){
if(p == NULL){
return false;
}
DNode *q = p->next; //找到p结点的后继结点q
if(q == NULL){
return false; //p结点没有后继结点
}
p->next = q->next;
if(q->next != NULL){ //q结点不是最后一个结点
q->next->prior=p; //修改后继结点的前项指针
}
free(q); //释放结点空间
return true;
}
双链表的销毁
依据双链表循环删除头结点的后继结点进行双链表的销毁
//销毁双链表
void DestoryList(DLinkList &L){
//循环释放各个数据结点
while(L->next != NULL){
DeleteNextDNode(L);
}
free(L); //释放头结点
L = NULL; //头指针指向NULL
}
双链表的遍历
前项遍历
//前向遍历
while(p!=NULL){
//对接点p要进行相应的处理,如打印
p = p->prior;
}
//前向遍历跳过头结点
while(p->prior!=NULL){
p = p->prior;
}
后向遍历
//后项遍历
while(p!=NULL){
//对接点p要进行相应的处理,如打印
p = p->next;
}
双链表不可随机存取,按位查找、按值查找操作都只能用便利的方式实现。
时间复杂度:O(n)