C++自己实现list

C++自己实现list

  前两个博客发表了自己写的stack(栈)和queue(队列),感觉比较简单,今天想试着实现list,结果发现,不是那么容易,感觉自己对STL的底层不是很了解,

真要自己实现还真的很难,看STL的源代码,那个晕啊...那代码也写得太难理解了,当然跟我不了解有关,但我相信,在将来的某一天我会懂的,你看我的代码也会懂的。

  话说:STL中的list的内部结构就是一个双向链表,这个东东以前还真没有玩过,就凭他用的是双向链表我就不想用他,指针太多,耗资源,当然存在就有他的价值,

他能快速访问其中的元素。废话总该少说,代码就该多些。

  有那么一点高兴的是实现双向链表的翻转,其他的没什么了,list还没有实现,由于现在能力有限,新的版本一定会发布的,你就将就着看吧!

#include <iostream> using namespace std; template<typename T> class list { public : list() { initialize(); } list(int count) { initialize(); if(count>0) { for(int i=0;i<count;i++) { push_front(0); } } } list(int count,T data) { initialize(); if(count>0) { for(int i=0;i<count;i++) { push_front(data); } } } //显示最后一个节点 T& back() { checkEmpty(); return cur->data; } T& back() const { return back(); } //显示第一个节点 T& front() { checkEmpty(); return head->next->data; } T& front() const { return front(); } //弹出最后一个节点 void pop_back() { checkEmpty(); cur=cur->prev; delete cur->next; cur->next=NULL; --len; } //弹出第一个节点 void pop_front() { checkEmpty(); node* tmp=head->next; head->next=tmp->next; tmp->prev=head; delete tmp; --len; } //前插节点 void push_front(const T& t) { node* newNode=new node(t); head->next=newNode; newNode->prev=head; ++len; } //后插节点 void push_back(const T& t) { node* newNode=new node(t); newNode->prev=cur; cur->next=newNode; cur=newNode; ++len; } //删除所有值为t的节点 void remove(const T& t) { checkEmpty(); node* tmp=head->next; for(int i=0;i<len;i++) { if(tmp->data!=t) { tmp=tmp->next; continue; } if(tmp->next==NULL)//删除最后一个节点 { cur=tmp->prev; //将当前节点指向最后一个节点的前一个节点 cur->next=NULL;//由于保持当前节点指向最后一个节点,他的下一个节点当然为空 }else //删除中间节点 { tmp->prev->next=tmp->next; //要删除节点的前一个节点的next指针指向要删除节点的下一个节点 tmp->next->prev=tmp->prev; //要删除节点的下一个节点的prev指针指向要删除节点的前一个节点 } --len; node* t=tmp->next; delete tmp; tmp=t; } } //反转链表 //每次都修改当前节点的前后节点指针 //最后一个节点的下一个指针指向前一个节点 void reverse() { checkEmpty(); node* prev = head;// 上一个节点 node* pcur = head->next;//当前节点 node* next; while (pcur !=NULL) { if(!pcur->next) { pcur->next=prev;//最后一个节点的下一个节点指向前一个节点 break; } next = pcur->next; //下一个节点 pcur->next=prev; //修改当前节点的下一个节点 pcur->prev=next; //修改当前及诶单的上一个节点 prev=pcur; //将当前节点设为上一个节点 pcur=next; //将下一个节点设为当前节点 } cur=head->next; //末节点指向头节点 head->next=pcur; //头指针指向当前节点,也就是指向翻转之前的末节点 } //排序 //节点之间直接交换数据,而没有用修改指针指向 void sort() { if(empty()) { return; } node *p,*t; p=head->next; T d; while(p!=NULL) { t=p; while(t!=NULL) { if(p->data>t->data) { d=p->data; p->data=t->data; t->data=d; } t=t->next; } p=p->next; } } //链表元素个数 int size() { return len; } void resize(int count) { resize(count,0); } //重新设置元素 void resize(int count,T t) { if(count<0) { throw new exception("元素的个数不能小于0!"); } clear(); //内存是必须释放的 while(count--) { push_front(t); } } //清空集合 void clear() { if(empty()) { return; } node *tmp=head; node *t=tmp->next; while(t!=NULL) { tmp=t; t=t->next; delete tmp; } tmp=NULL; t=NULL; cur=head;//当前节点指向头指针 } //链表是否为空 bool empty() const { return len==0; } //判断链表是否为空 void checkEmpty() { if(empty()) { throw new exception("集合中没有元素!"); } } private : typedef struct node1 { node1 *prev,*next; T data; node1(T t):data(t),prev(NULL),next(NULL){} }node; node* head;//头节点 node* cur; //当前节点,指向末节点 int len; //节点个数 void initialize() { cur=head=new node(-1); len=0; } };


作者:陈太汉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值