您的位置:首页 > 编程语言 > C语言/C++

c++单链表

2016-05-26 09:56 387 查看
slist.h

#ifndef _SLIST_H_INCLUDED
#define _SLIST_H_INCLUDED

#include <cassert>

template<typename T>
struct Slist_node {
T element;
Slist_node* next;
/*把结构体当作一个类,使用构造函数和析构函数初始化*/
Slist_node() : element(), next(0) {}//可以阻止不应该允许的经过转换构造函数进行的隐式转换的发生
explicit Slist_node(const T& elem) : element(elem), next(0) {}
~Slist_node() { next=0; }
};

template<typename T>
class Slist {

typedef Slist_node<T>* Ptrn;

public:
Slist() : hb_head(new Slist_node<T>), hb_size(0) {}
~Slist();
/*一系列对外接口*/
bool empty() const { return hb_size ? false : true; }
int size() const { return hb_size; }
void reverse();
//  void sort() const;
T value(int pos) const;

void push_front(const T& elem);
T pop_front();
void push_back(const T& elem);
T pop_back();

void insert_after(const T& elem, int pos);
T erase(int pos);
void erase(int beg, int end);
void clear();

private:
Slist_node<T>* hb_head;
int hb_size;
};

template<typename T>
Slist<T>::~Slist()//析构函数
{
clear();
delete hb_head;
}

template<typename T>
void Slist<T>::clear()//删除所有元素。
{
if (hb_size != 0)
erase(1,hb_size);
}

template<typename T>
void Slist<T>::erase(int beg, int end)//清除特定范围的函数
{
if (beg>hb_size || end > hb_size || beg<=0 || end<=0 || beg>end)//判断是否超出范围
std::cerr<<"error : position out of range!\n";
else {
Ptrn ptr=hb_head;
Ptrn prev=0;
int i=0;
while (i != beg) {//从开头查找beg位置且保留beg前的数据
prev=ptr;
ptr=ptr->next;
++i;
}
while (i <= end) {//删除beg~end之间的元素。
Ptrn ptm=ptr;
ptr=ptr->next;
delete ptm;
--hb_size;
++i;
}
prev->next=ptr;//两边要对接起来
}
}

template<typename T>
T Slist<T>::erase(int pos)//删除特定位置的某个元素
{
assert(pos<=hb_size && pos!=0);
/*现计算括号内条件 ,如果其值为假(即为0),那
么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行*/
Ptrn ptr=hb_head;
Ptrn prev=0;
int i=0;
while (i != pos) {//从头开始找到位置且保留前面的数据。
prev=ptr;
ptr=ptr->next;
++i;
}
T t=ptr->element;//复制要删除的元素的值
prev->next=ptr->next;
delete ptr;
--hb_size;
return t;
}

template<typename T>
void Slist<T>::insert_after(const T& elem, int pos)//在pos位置后插入elem
{
Ptrn ptr=hb_head;
int i=0;
while ( i!= pos) {
ptr=ptr->next;
++i;
}

Slist_node<T>* pSln=new Slist_node<T>;
pSln->element=elem;
pSln->next=ptr->next;
ptr->next=pSln;
++hb_size;
}

template<typename T>
void Slist<T>::push_front(const T& elem)//插入到首部
{
insert_after(elem,0);
}

template<typename T>
void Slist<T>::push_back(const T& elem)//插入到最后。
{
insert_after(elem,hb_size);
}

template<typename T>
T Slist<T>::pop_front()//删除第一位元素
{
return erase(1);
}

template<typename T>
T Slist<T>::pop_back()//删除最后一位元素
{
return erase(hb_size);
}

template<typename T>
inline T Slist<T>::value(int pos) const//查看当前位置pos对应的值。
{
Ptrn ptr=hb_head;
int i=0;
while (i != pos) {
ptr=ptr->next;
++i;
}
return ptr->element;
}

template<typename T>
void Slist<T>::reverse()//单链表反转。
{
P
4000
trn pbeg=hb_head->next;//备份原链表头节点
hb_head->next=0;        //设置当前头节点
hb_size=0;
Ptrn ptr=pbeg;          //原地址赋给ptr
while (ptr != 0) {
push_front(ptr->element);//将后面的元素依次插入到首部。
Ptrn ptm=ptr;           //删除当前位置的刚插入的元素。
ptr=ptr->next;
delete ptm;
}
}

#endif


test.cpp

#include <iostream>
#include "slist.h"

int main()
{
Slist<int> slist;
int i=slist.size();
std::cout<<i<<std::endl;

slist.push_back(2);
for (int j1=0; j1<slist.size(); ++j1)
std::cout<<slist.value(j1+1)<<'-';
std::cout<<std::endl;
slist.push_front(4);
for (int j2=0; j2<slist.size(); ++j2)
std::cout<<slist.value(j2+1)<<'-';
std::cout<<std::endl;
slist.insert_after(7,1);
i=slist.size();
std::cout<<i<<std::endl;
for (int j3=0; j3<slist.size(); ++j3)
std::cout<<slist.value(j3+1)<<'-';
std::cout<<std::endl;

slist.reverse();
std::cout<<slist.size()<<std::endl;
for (int j4=0; j4<slist.size(); ++j4)
std::cout<<slist.value(j4+1)<<'-';
std::cout<<std::endl;
slist.clear();
std::cout<<slist.size()<<std::endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构