单向循环链表(建表、插入、删除、输出)
2016-06-26 16:08
399 查看
这个写法部分参考计蒜客,目前正在学习该网站的数据结构课程。
其实,这个写法看得很变扭,我适当的改了一下,感觉还是很变扭,莫非是我改变扭了?。。。
这里用插入函数来完成建表,所以插入函数既可以在建表时使用,也可以在建表完成后再进行插入时使用。
删节点的函数既可以删除整个表,也可以删除某个节点。
(Ps:这里由于函数有两个用途,所以在删除第一个节点时需要判断,判断删除第一个节点后是否还有节点,如果表已经剩下第一个节点了,注意将tail置为NULL,方便输出判断。如果删除第一个结点后还有节点,则进行相应的操作)
特别需要注意删除最后一个节点时尾指针需要更新
如果有错误的话欢迎指出,谢谢
其实,这个写法看得很变扭,我适当的改了一下,感觉还是很变扭,莫非是我改变扭了?。。。
这里用插入函数来完成建表,所以插入函数既可以在建表时使用,也可以在建表完成后再进行插入时使用。
删节点的函数既可以删除整个表,也可以删除某个节点。
(Ps:这里由于函数有两个用途,所以在删除第一个节点时需要判断,判断删除第一个节点后是否还有节点,如果表已经剩下第一个节点了,注意将tail置为NULL,方便输出判断。如果删除第一个结点后还有节点,则进行相应的操作)
特别需要注意删除最后一个节点时尾指针需要更新
#include <iostream> #include <stdlib.h> using namespace std; class Node { public: int data; Node *next; public: Node(int _data){ data = _data; next = NULL; } }; class LinkList { private: Node *tail; public: LinkList(){ tail = NULL; } /*注意index的含义,这里将链表下标看成从1开始*/ /*默认输入的n合法*/ void insertNode(Node *node, int index){ /*当前链表为空,则将插进来的节点作为头节点,并且将它的指针指向自己,形成循环*/ if(tail==NULL){ tail = node; tail->next = tail; //cout<<"if(tail==NULL)"<<endl; return; } /*建表成功后的额外插入到链表首位置的判断语句*/ /*tail->next表示第一个节点,那么node->next = tail->next则将node插到表头之前,形成新的表头*/ /*tail为最后一个节点,表头更新了,所以tail->next=node*/ if(index==1){ node->next = tail->next; tail->next = node; return; } int tot = 1; Node *currentNode = tail->next; /*curentNode代表头结点*/ /*注意判断条件*/ while(currentNode != tail && tot < index-1){ currentNode = currentNode->next; tot++; } /*理解currentNode代表的值*/ if(tot == index-1){ node->next = currentNode->next; currentNode->next = node; //cout<<"if(tot==index-1):"<<endl; } /*将node插入到当前链表末尾时,将进行这个判断*/ /*判断时,tail还没更新,代表倒数第二个节点,而node代表最后一个节点*/ if(node == tail->next){ tail = node; //cout<<"if(node==tail->next)"<<endl; } } void deleteNode(int index){ int tot = 1; Node *currentNode, *NodeOfDelete; if(tail==NULL){ //cout<<"链表已空!!!"<<endl; return; } /*链表长度等于1时*/ if(index==1 && (tail->next)==tail) { NodeOfDelete = tail; delete NodeOfDelete; tail = NULL; return; } /*链表长度大于等于2时*/ if(index==1 && (tail->next->next)!=NULL ) { NodeOfDelete = tail->next; tail->next = NodeOfDelete->next; delete NodeOfDelete; return; } currentNode = tail->next; while(currentNode != tail && tot<index-1){ currentNode = currentNode->next; tot++; } /*得在删除最后一个节点前更新tail*/ if(currentNode->next == tail) tail = currentNode; /*包含尾节点删除*/ if(tot==index-1){ NodeOfDelete = currentNode->next; currentNode->next = NodeOfDelete->next; delete NodeOfDelete; } } void outputList(){ int tot = 1; if(tail==NULL){ cout<<"链表已空!!!"<<endl; return; } Node *currentNode = tail->next; while(currentNode != tail){ cout<<currentNode->data<<" "; currentNode = currentNode->next; } /*尾节点由于循环条件影响需要额输出*/ cout<<currentNode->data<<endl; cout<<"-------------分割线-------------------\n\n\n"; } }; int main() { int n; while(cin>>n){ LinkList linklist; for(int i=1; i<=n; i++){ Node *node = new Node(i); linklist.insertNode(node, i); } linklist.outputList(); /*下面的试验n的大小有限制*/ cout<<"删除第一个节点:"<<endl; linklist.deleteNode(1); linklist.outputList(); cout<<"删除第3个节点:"<<endl; linklist.deleteNode(3); linklist.outputList(); cout<<"删除最后一个节点:"<<endl; linklist.deleteNode(n-2); linklist.outputList(); cout<<"删除列表并且额外删除两次看看如何:"<<endl; for(int i=0; i<n;i++){ linklist.deleteNode(1); linklist.outputList(); } system("pause"); } return 0; }
如果有错误的话欢迎指出,谢谢
相关文章推荐
- Git 的 .gitignore 配置
- 提高工作效率的工具
- Prim(普里姆)算法求最小生成树的思想及C语言实例讲解
- java web开发第一篇记录
- 常见通信RF指标的内在和意义
- 为什么百度云可以给每位用户分配两T的存储空间?
- mybatis中使用in查询时的注意事项
- Makefile
- 输入一个数组,求最小的K个数
- mybatis中使用in查询时的注意事项
- java关键字、标识符
- Rolling Variance
- WebService三大基本元素 SOAP WSDL UDDI
- python - 类的特殊成员
- URL和URI的区别和联系
- KMP
- 1A. Theatre Square
- C++拷贝构造函数详解
- ajax练习习题三搜索
- GDB技巧整理