模板和STL 4(1)

模板和STL 4
容器==》双向线性链表容器==》{基础设施 析构、析构、深拷贝 获取首元素 向首部压入 从首部弹出 删除所有匹配元素 清空、判空和大小 针对char const*类型的特化}

双向线性链表容器
基础设施
在这里插入图片描述
基础设施
节点及其指针
–templateclass List{
private:
class Node{
public:
Node(T const& data,Node* prev=NULL,Node* next=NULL):m_data(data),m_prev(prev),
m_next(next){}
T m_data;
Node* m_prev,
Node* m_next;
};
Node* m_head,
Node* m_tail;
};

构造、析构、深拷贝
构造函数初始化空链表,析构函数销毁剩余节点,拷贝构造函数和拷贝赋值运算符函数支持深拷贝;
–templateclass List{
List(void):m_head(NULL),m_tail(NULL){}
~List(void){clear();}
List(List const& that):m_head(NULL),m_tail(NULL){
for(Node* node=that.m_head;node;node=node->m_next)
push_back(node->m_data);
}
List& operator=(List const& rhs){
if(&rhs!=this){
List list=that;
swap(m_head,list.m_head);
swap(m_tail,list.m_tail);
}
return *this;
}
};

获取首元素
通过普通容器获取其首元素的左值引用,通过常容器获取其首元素的常左值引用,后者应能够复用前者的实现
–templateclass List{
public:
T& front(void){
if(empty()){
throw underflow_error(“链表下溢!”);
return m_head->m_data;
}
T const& front(void)const{
return const_cast<List*>(this)->front();
}
};

向首部压入
在首节点的前面增加新节点,使新节点成为新的首节点
–templateclass List{
public:
void push_front(T const& data){
m_data=new Node(data,NULL,m_head);
if(m_head->m_next){
m_head->m_next->m_prev=m_head;}
else{
m_tail=m_head;}
}
};

从首部弹出
.删除首节点,使被删除节点的后节点成为新的首节点
–templateclass List{
public:
void pop_front(void){
if(empty())
throw underflow_error(“链表下溢!”);
Node* next=m_head->m_next;
delete m_head;
m_head=next;
if(m_head)
m_head->m_prev=NULL;
else m_tail=NULL;
}
};

删除所有匹配元素
遍历的同时判断是否相等,删除所有满足条件的节点
–templateclass List{
void remove(T const& data){
for(Node* node=m_head,*next;node;node=next){
next =node->m_next;
if(node->m_data ==data){
if(node->m_prev)
node->m_prev->m_next=node->m_next;
else
m_head=node->m_next;
if(node->m_next)
node->m_next->m_prev = node->m_prev;
else
m_tail =node->m_prev;
delete node;}
}
}
};

清空、判空和大小
.在遍历中删除所有节点
–templateclass List{
void clear(void){
for(Node* next;m_head;m_head=next){
next=m_head->m_next;delete m_head;}
m_tail=NULL;}
bool empty(void) const{
return !m_head&&!m_tail;}
size_t size(void)const{
size_t nodes=0;
for(Node* node=m_head;node;node =node->m_next)
++nodes;
return nodes;}
};

针对char const类型的特化
将类型相关的操作与类型无关的操作分开
–templateclass List{
void remove(T const& data){
for(Node
node=m_head,*next;node;node=next){
next=node->m_next;
if(equal(node->m_data,data)){
if(node->m_prev)
node->m_prev->m_next =node->m_next;
else m_head=node->m_next;
if(node->m_next)
node->m_next->m_prev =node->m_prev;
else m_tail =node->m_prev;
delete node;
}
}
}
};

针对char const类型的特化
分别实现equal函数的通用版本和特化版本
–templateclass List{
private:
bool equal(T const& a,T const& b)const{
return a==b;
}
};
–template<>bool List<char const
>::equal(char const* const& a,char const* const& b)const{
return !strcmp(a,b)==0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值