对于不是循环的双向链表:
写成程序时画图示意一下:几个特殊点注意一下尤其注意空指针
插入结点分为: 双向链表为空, 和双向链表表非空两种情况
删除结点分为: 删除头结点和删除其他结点两种情况, 在删除头结点时需注意: 双向链表只含一个头结点的情况和含有多个结点删除头结点的情况
删除其他结点时需注意 删除尾结点时,指针的特殊情况
双向非循环链表的操作和单链的操作基本一致:
双向非循环链表的插入和删除操作参考代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
//以下为双向链表的操作
typedef struct DoubleListNode
{
int data;
DoubleListNode *prior,*next;
}DoubleListNode;
//尾插法建立双向链表
void AddNodeToTail(DoubleListNode**pHead,int value)//插入结点分为: 双向链表为空, 和双向链表表非空两种情况
{
DoubleListNode *pNew=new DoubleListNode;
pNew->data=value;
pNew->prior=pNew->next=NULL;
if(*pHead==NULL)
{
*pHead=pNew;
}
else
{
DoubleListNode* pNode=*pHead;
while(pNode->next!=NULL)//找到尾结点
{
pNode=pNode->next;
}
pNode->next=pNew;
pNew->prior=pNode;
}
}
//删除结点分为: 删除头结点和删除其他结点两种情况, 在删除头结点时需注意: 双向链表只含一个头结点的情况和含有多个结点删除头结点的情况
//删除其他结点时需注意 删除尾结点的是指针的特殊情况
void RemoveNode(DoubleListNode**pHead,int value)
{
if(pHead==NULL||*pHead==NULL)
{
return ;
}
DoubleListNode *pToBeDelete=NULL;
if((*pHead)->data==value)//删除双向链表的头结点
{
pToBeDelete=*pHead;
*pHead=(*pHead)->next;
if(*pHead!=NULL)//此种情况为删除只有一个头结点的情况
{
(*pHead)->prior=NULL;
}
}
else//删除双向链表中的其它结点
{
DoubleListNode *pNode=*pHead;
while(pNode->next!=NULL&&pNode->next->data!=value)//找到删除结点的前驱结点
{
pNode=pNode->next;
}
if(pNode->next!=NULL&&pNode->next->data==value)
{
pToBeDelete=pNode->next;
pNode->next=pToBeDelete->next;
if(pToBeDelete->next!=NULL)//考虑删除尾结点的情况
{
pToBeDelete->next->prior=pNode;
}
}
}
if(pToBeDelete!=NULL)
{
delete pToBeDelete;
pToBeDelete->prior=pToBeDelete->next=NULL;
}
}
void PrintList(DoubleListNode*pHead)
{
if(pHead==NULL)
{
return;
}
DoubleListNode *pNode=pHead;
while(pNode!=NULL)//对于单链表的判断此处while(pNode!=NULL)
{
cout<<pNode->data<<" -->";
pNode=pNode->next;
}
cout<<"NULL"<<endl;
}
int main()
{
DoubleListNode *pHead=NULL;
for(int i=1;i<=10;i++)
{
AddNodeToTail(&pHead,i);
}
PrintList(pHead);
RemoveNode(&pHead,7);//删除中间结点
PrintList(pHead);
for(int i=1;i<=10;i++)//一直删除头结点
{
RemoveNode(&pHead,i);
PrintList(pHead);
}
for(int i=1;i<=10;i++)
{
AddNodeToTail(&pHead,i);
}
PrintList(pHead);
for(int i=10;i>=0;i--)//一直删除尾结点
{
RemoveNode(&pHead,i);
PrintList(pHead);
}
return 0;
}
双向循环操作的考虑的东西要稍微多一点点:
基本也一样:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
//以下为双向循环链表的操作
typedef struct DoubleListNode
{
int data;
DoubleListNode *prior,*next;
}DoubleListNode;
//尾插法建立循环双向链表 对于非空双向循环链表先找到尾结点pNode=(*Phead)->prior;
void AddNodeToTail(DoubleListNode**pHead,int value)
{
DoubleListNode *pNew=new DoubleListNode;
pNew->data=value;
pNew->prior=pNew->next=NULL;
if(*pHead==NULL)//注意对于尾插法的循环双向链表来说,(*pHead)->prior 即为尾节点 插入很容易
{
*pHead=pNew;
pNew->next=pNew->prior=pNew;
}
else
{
DoubleListNode *pNode= (*pHead)->prior;//pNode 指向了原来的尾结点
pNew->next=*pHead;//尾插法新节点的后继为头结点
pNew->prior=pNode;
pNode->next=pNew;
(*pHead)->prior=pNew;
}
}
void RemoveNode(DoubleListNode**pHead,int value)
{
if(pHead==NULL||*pHead==NULL)
{
return ;
}
DoubleListNode *pToBeDelete=NULL;
if((*pHead)->data==value&&(*pHead)->next==(*pHead))//删除只含一个结点循环双向链表 此处的条件一定不能错
{
pToBeDelete=*pHead;
*pHead=NULL;
}
else if((*pHead)->data==value)//删除含多个元素的头结点
{
pToBeDelete=*pHead;
*pHead=(*pHead)->next;//原先头结点的的下个结点更新为新的头指针
(*pHead)->prior=pToBeDelete->prior;//头结点的前驱指向尾结点
pToBeDelete->prior->next=*pHead;//尾结点的后继指向头结点
}
else//删除双向链表中的其它结点
{
DoubleListNode *pNode=*pHead;
while(pNode->next!=(*pHead)&&(pNode->next->data!=value))//找到删除结点的前驱结点
{
pNode=pNode->next;
}
if(pNode->next!=(*pHead)&&(pNode->next->data==value))
{
pToBeDelete=pNode->next;
pNode->next=pToBeDelete->next;//这里绝对不能搞错。
pToBeDelete->next->prior=pNode;
}
}
if(pToBeDelete!=NULL)
{
delete pToBeDelete;
//pToBeDelete->prior=pToBeDelete->next=NULL;
}
}
void PrintList(DoubleListNode*pHead)
{
if(pHead==NULL)
{
return;
}
DoubleListNode *pNode=pHead;
while(pNode->next!=pHead)//对于单链表的判断此处while(pNode!=NULL)
{
cout<<pNode->data<<" -->";
pNode=pNode->next;
}
cout<<pHead->prior->data<<" -->";//打印最后一个结点
cout<<"NULL"<<endl;
}
int main()
{
DoubleListNode *pHead=NULL;
for(int i=1;i<=10;i++)
{
AddNodeToTail(&pHead,i);
}
PrintList(pHead);
RemoveNode(&pHead,7);//删除中间结点
PrintList(pHead);
for(int i=1;i<=10;i++)//一直删除头结点
{
RemoveNode(&pHead,i);
PrintList(pHead);
}
for(int i=1;i<=10;i++)
{
AddNodeToTail(&pHead,i);
}
PrintList(pHead);
for(int i=10;i>=0;i--)//一直删除尾结点
{
RemoveNode(&pHead,i);
PrintList(pHead);
}
return 0;
}