C++自己实现list

 C++自己实现list

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

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

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

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

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

源码
#include <iostream>
usingnamespace 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)
{
thrownew 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())
{
thrownew 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;
}
};

作者:陈太汉

posted @ 2011-07-21 19:00  啊汉  阅读(8354)  评论(16编辑  收藏  举报