双向链表的插入删除操
来源:互联网 发布:局域网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
- 双向链表的插入删除操
- 双向循环链表的插入删除
- 双向链表的建立插入删除
- 双向链表的创建/插入/删除
- 双向链表的插入与删除
- 双向链表的生成,删除,插入
- 双向链表的插入以及删除
- 双向链表的插入、删除、遍历
- 双向链表的插入和删除
- 双向链表的插入与删除
- 双向链表插入删除
- 双向循环链表的插入和删除
- 双向链表的插入和删除算法
- 双向链表的插入删除和查询
- 双向循环链表的创建,插入与删除。
- 双向链表的建立插入与删除
- 双向循环链表的创建,插入,删除操作
- 双向链表的建立、删除/插入节点
- UVA 11997 K Smallest Sums(优先队列)
- 杭电ACM5327
- android api实现高斯模糊,且兼容低版本
- CF 439D Devu and his Brother
- codeforces244C. Checkposts
- 双向链表的插入删除操
- Sys.WebForms.PageRequestManagerServerErrorException: 在服务器上处理请求时出现未知错误解决办法
- Ubuntu 安装mysql和简单操作
- JAVA学习第十二天
- 鸟哥的linux私房菜学习笔记十一 ,命令权限
- 如何清晰地思考:近一年来业余阅读的关于思维方面的知识结构整理(附大幅思维导图)
- 6. CSS 属性选择器
- k最近邻算法(KNN)的简介和python实现
- 在windows下安装linux操作系统