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;
}
};
复制代码

作者:陈太汉

文转自啊汉博客园博客,原文链接:http://www.cnblogs.com/hlxs/archive/2011/07/21/2113178.html

目录
相关文章
|
3天前
|
算法 C++ 容器
模拟实现c++中的list模版
模拟实现c++中的list模版
|
2月前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
44 1
|
2月前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
69 7
|
2月前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
28 4
|
4月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
103 2
|
4月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
33 1
|
4月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
91 5
|
4月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
103 2
|
4月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(三)
【C++】C++ STL 探索:List使用与背后底层逻辑
|
4月前
|
C++
【C++】C++ STL 探索:List使用与背后底层逻辑(二)
【C++】C++ STL 探索:List使用与背后底层逻辑