#include#include #include using namespace std; typedef struct { int num; //学号 char name[10]; //姓名 } student; template class h; template class stu { private: stu *p_prior; stu *p_next; student data; public: stu() { p_prior=NULL; p_next=NULL; } ~stu() { p_prior=NULL; p_next=NULL; } friend class h ; }; template class h { private: stu *head; public: h() { head=new stu (); } h(stu *note) { head=note; } ~h() { delete head; } public: bool inserts(char _name[10],int _num,int i); void display(); bool deletes(int n); bool find(int n); bool cleanh(); }; //插入运算 (此处current指针名字设置的不合理,因为它的功能是指向插入节点的前一个结点) template bool h ::inserts(char _name[10],int _num,int n) { if (n<1) //n不合理 { cout << "输入非有效位置" << endl; return false; } if(!(head->p_next)) //链表为空 { cout<<"链表为空!"< * newnode = new stu ; //创建新节点 if (newnode == NULL) { cout << "内存分配失败,新结点无法创建" << endl; return false; } newnode->data.num=_num; strcpy(newnode->data.name,_name); stu * current = head; //创建新指针,并设置游标指针current if(n==1) //插入的是第一位 { if(current->p_next) //newnode不为最后一个 { current->p_next->p_prior=newnode; newnode->p_next=current->p_next; } head=newnode; } else { for(int i=1;i p_next; } if(!(current)) { cout<<"找不到位点!"< p_next) //newnode不为最后一个 { current->p_next->p_prior=newnode; newnode->p_next=current->p_next; } current->p_next=newnode; newnode->p_prior=current; } return true; } //预览运算 template void h :: display() { if(!head) { cout<<"链表为空!"< * current = head; while(current) { cout<<"姓名:"< data.name<<'t'<<"学号:"< data.num< p_next; } } //删除运算 template bool h :: deletes(int n) { if (n<1) //n不合理 { cout << "输入非有效位置" << endl; return false; } if(!(head->p_next)) //链表为空 { cout<<"链表为空!"< * current = head; stu * p = head; stu * q = head; if(n==1) //删的是第一个结点 { head=head->p_next; delete current; } else { for(int i=1;i p_next; //指向删除位点的前一位 } current=p->p_next; if(current->p_next) //删的不是最后一个结点 { q=current->p_next; p->p_next=q; q->p_prior=p; delete current; } else { p->p_next=NULL; delete current; } } } //查找运算 template bool h :: find(int n) { if (n<1) //n不合理 { cout << "输入非有效位置" << endl; return false; } if(!(head->p_next)) //链表为空 { cout<<"链表为空!"< * current = head; while(current) { if(current->data.num==n) { cout<<"学生信息:"< data.name<<'t'<<"学号:"< p_next; } cout<<"查找失败!"< bool h :: cleanh() { stu * current = head; while(current) { head=head->p_next; delete current; current=head; } return true; } int main() { stu note; h link(¬e); cout << "*******************************操作选择*******************************" << endl; cout << "1.产生链表" << endl; cout << "2.给链表中插入元素" << endl; cout << "3.删除链表中的元素" << endl; cout << "4.获取链表中的元素" << endl; cout << "5.清空链表中的元素" << endl; cout << "**********************************************************************" << endl; while(1) { int o_num; cout<<"请输入操作数:"< >o_num; switch(o_num) { case 1: //产生链表 { int num; char name[10]; for(int i=1;i<=4;i++) { cout<<"请输入第"<>name; cout<<"请输入第"<>num; if(!(link.inserts(name,num,i))) { cout<<"链表生成失败!"< >n; cout<<"请输入学生的姓名:"< >name; cout<<"请输入学生的学号:"< >num; if(!(link.inserts(name,num,n))) { cout<<"插入失败!"< >n; if(!(link.deletes(n))) { cout<<"删除失败!"< >n; link.find(n); break; } case 5: //清空运算 { if(link.cleanh()) { cout<<"清除完毕!"< (这位大佬为我这段代码提供了很多灵感!传送门~:利用C++实现双向链表的基本操作_何当共剪西窗竹的博客-CSDN博客_c++ 双向链表)
本人是大一下的学生。第一次完成那么复杂的代码段,特地以此文记录这过程中我遇到的问题。PS:本人模板类的概念还没学过(所以只能靠自己瞎学瞎猜瞎写),写的代码很可能会不专业,仅供大家参考!
1.拜托以后不要这么用模板类了,好好的datatype改成student干什么,doubleNode就doubleNode了改成stu干什么……虽然这样改确实好记,而且字数也少啊哈哈哈哈
2.其实这种双向链表人家是要有个头结点的……但是因为我太逊了,所以就没有。关键是这种头结点要再定义一个class,我层次太低了,两个class就够我受的了。话说我暂时还没在网上找到创建有头结点的双向链表的代码或者教程耶……过几天请教一下老师吧(话说我们数据结构的老师是真的屑,要不然我也不至于到csnd社区自学啊!ε=(´ο`*)))唉,tnn。)
3.上面提到的那个大佬给了我很多启发,其中一个就是用friend来把两个class联系起来!真的太棒了!我个菜鸡只知道private和public,我是真的屑。(不过两个class要提前声明哦!)
4.在我自己写代码的时候,出现了一个罕见的报错:error : Cannot access memory at address 0x0。屏幕显示:Program received signal SIGSEGV , Segmentation fault .实际上这就是指针出现问题了。我的实际情况是:让一个指向最后一个结点的指针后移,然后误以为这个指针指向了某一结点(实际上人家已经指向NULL了)。当我对这个被人深深误解的指针进行操作时,自然就报错了。这种情况在链表里面是很常见的!
5.其实链表最重要的是要把指针弄清楚。关于指针我还出现了这样一个错误:把指针闭合成一个环,搞成循环了。其实这就是我不好好画图,搞不清指针指向的后果。
6.在这其中我还遇到过一个很诡异的情况:当我需要输入int型数据的时候,我输入了中文,然后……就死循环了?!!这…这是什么情况?我不理解,但大为震撼!!
7.当然还有很多脑残的小错误,比如写了while(current)又忘记让current后移的;把while(current)写成if(current)的;还有if(!布尔函数)和if(布尔函数)乱七八糟用的;用case不加break的;还有创建了动态储存变量要记得delete……
8.在复杂的程序里,思路越清晰越好!只用一两个指针操作看起来帅,但是思路容易变乱(就比如我这次的查找函数就没写好,如果再多一个指针,思路就会更清晰明了了),那就多来几个指针,把需要操作的结点统统分配个游标指针!(ps:一定要好好注意特殊情况,比如输入非法啊,链表为空啊,链表位置不够啊之类的,养成好习惯噢!思维要缜密!)。如果情况太多,那就一种一种情况拆出来,每个情况都if-else一下!虽然看起来笨拙,但走的快不一定赢,脚踏实地不留bug才是成功!
9.使用有那么多函数的class,要好好用bool这个功能,及时发现问题。其次,我调试效率不太高,每次都要新建链表再输入数据初始化,很麻烦,不知道还有什么更好的方法呢?



