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

c++模板实现自定义链表及操作

2014-11-17 14:47 525 查看
今天花时间整理了一下C++模板方面的知识,搞了一个小程序作为实践


下面是头文件:chain.h

#include <iostream>
using namespace std;

template <class T> class Chain;

template <class T>
class ChainNode {
friend class Chain<T>;
private:
T data;
ChainNode<T> *link;
};

template<class T>
class Chain{
public:
Chain() {first = 0;}
~Chain() ;
bool IsEmpty() const {return first == 0;}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
void Erase();
Chain<T>& Append(const T& x);
Chain<T>& Delete(int k, T& x);
Chain<T>& Insert(int k, const T& x);
void Output(ostream& out) const;
private:
ChainNode<T> *first; //指向第一个节点的指针
};

class OutOfBounds
{
public:
// 构造函数,参数为错误代码
OutOfBounds(int errorId)
{
// 输出构造函数被调用信息
std::cout << "MyExcepction is called" << std::endl;
m_errorId = errorId;
}

// 拷贝构造函数
OutOfBounds( OutOfBounds& myExp)
{
// 输出拷贝构造函数被调用信息
std::cout << "copy construct is called" << std::endl;
this->m_errorId = myExp.m_errorId;
}

~OutOfBounds()
{
// 输出析构函数被调用信息
std::cout << "~MyExcepction is called" << std::endl;
}

// 获取错误码
int getErrorId()
{
return m_errorId;
}

private:
// 错误码
int m_errorId;
};
以下是源文件:chain.cpp

#include "chain.h"

template<class T>
Chain<T>::~Chain( )
{
//链表的析构函数,用于删除链表中的所有节点
ChainNode<T> *next; //下一个节点
while (first) {
next = first->link;
delete first;
first = next;
}
}

template<class T>
int Chain<T>::Length() const
{
//返回链表中的元素总数
ChainNode<T> *current = first;
int len = 0;
while (current) {
len++;
current = current->link;
}
return len;
}

template<class T>
bool Chain<T>::Find(int k, T& x) const
{
//寻找链表中的第 k个元素,并将其传送至 x
//如果不存在第 k个元素,则返回false,否则返回true
if (k < 1) return false;
ChainNode<T> *current = first;
int index = 1; // current 的索引
while (index < k && current) {
current = current->link;
index++;
}

if (current) {x = current->data; return true;}
return false; //  不存在第k个元素
}

template<class T>
int Chain<T>::Search(const T& x) const
{
//寻找x,如果发现x,则返回x的地址
//如果x不在链表中,则返回 0
ChainNode<T> *current = first;
int index = 1; // current 的索引
while (current && current->data != x) {
current = current->link;
index++;
}

if (current) return index;
return 0;
}

template<class T>
void Chain<T>::Output(ostream& out) const
{
//将链表元素送至输出流
ChainNode<T> *current;
for (current = first; current; current = current->link)
out << current->data << " ";
}

//重载<<
template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out);
return out;
}

template<class T>
Chain<T>& Chain<T>::Delete(int k, T& x)
{
//把第k个元素取至x,然后从链表中删除第 k个元素
//如果不存在第 k个元素,则引发异常 OutOfBounds
if (k < 1 || !first)
throw new OutOfBounds(-1); // 不存在第k个元素
//p最终将指向第 k个节点
ChainNode<T> *p = first;
//将p移动至第k个元素,并从链表中删除该元素
if (k == 1){ //p已经指向第k个元素
first = first->link; //  删除之
} else { //用q指向第k - 1个元素
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q; index++) {
q = q->link;
}

if (!q || !q->link) {
throw new OutOfBounds(-2); //不存在第k个元素
}
p = q->link; //存在第k个元素
q->link = p->link; //从链表中删除该元素
}
//保存第k个元素并释放节点p
x = p->data;
delete p;
return *this;
}

template<class T>
Chain<T>& Chain<T>::Insert(int k, const T& x)
{
//在第k个元素之后插入x
//如果不存在第 k个元素,则引发异常OutofBounds
//如果没有足够的空间,则传递NoMem异常
if (k < 0) throw new OutOfBounds(-1);
//p最终将指向第 k个节点
ChainNode<T> *p = first;
//将p移动至第k个元素
for (int index = 1; index < k && p; index++)
p = p->link;
if (k > 0 && !p) throw new OutOfBounds(-1); //不存在第k个元素
//插入
ChainNode<T> *y=new ChainNode<T>;
y->data = x;
if (k)
{//在p之后插入
y->link = p->link;
p->link = y;
}
else {//作为第一个元素插入
y->link = first;
first = y;
}

return *this;
}

template<class T>
void Chain<T>::Erase()
{
//删除链表中的所有节点
ChainNode<T> *next;
while (first) {
next = first->link;
delete first;
first = next;
}
}

template <class T>
Chain<T>& Chain<T>::Append(const T& x)
{
//在链表尾部添加x
ChainNode<T> *y;
ChainNode<T> *last;
y = new ChainNode<T>;
y->data = x;
y->link = 0;
last = first;
if (first) {//链表非空
while(last->link){
last = last->link;
}

last->link = y;
last = y;
} else {//链表为空
first = last = y;
}

return *this;
}

template<class T>
class ChainIterator {
public:
T* Initialize(const Chain<T>& c)
{
location = c.first;
if (location)
return &location->data;
return 0;
}

T* Next()
{
if (!location)
return 0;
location = location->link;

if (location)
return &location->data;
return 0;
}

private:
ChainNode<T> *location;
};

int main(int argc, char **argv)
{
Chain<int> intChain;
int x = 5;
intChain.Append(x);
intChain.Append(1);
intChain.Append(2);
cout<<"after append:"<<intChain;
intChain.Delete(intChain.Length(), x);
cout<<std::endl<<x<<" was deleted"<<std::endl;
cout<<"after delete:"<<intChain<<endl;
intChain.Append(9);
cout<<"after append:"<<intChain<<endl;
intChain.Insert(3, 15);
cout<<"after insert(3, 15):"<<intChain<<endl;
cout<<"chain test"<<std::endl;
return 0;
}


编译:g++ -o chain chain.cpp chain.h

运行:./chain

结果:

after append:5 1 2 

2 was deleted

after delete(intChain.Length()):5 1 

after append:5 1 9 

after insert(3, 15):5 1 9 15 

chain test
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: