双向链表的插入删除操

来源:互联网 发布:局域网ip mac扫描软件 编辑:程序博客网 时间:2024/05/12 04:22

对于不是循环的双向链表:

写成程序时画图示意一下:几个特殊点注意一下尤其注意空指针

插入结点分为: 双向链表为空, 和双向链表表非空两种情况

删除结点分为 删除头结点和删除其他结点两种情况 在删除头结点时需注意: 双向链表只含一个头结点的情况和含有多个结点删除头结点的情况

删除其他结点时需注意 删除尾结点时,指针的特殊情况

双向非循环链表的操作和单链的操作基本一致:


双向非循环链表的插入和删除操作参考代码:

#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;}




0 0
原创粉丝点击