C++(超级简单)通用链表类似Java集合类接口

之前写的那个重载的是全局的operator==,operator!= 操作符,实际意义上不是一个通用的做法,改成了重载成员的 operator==,operator!=

// 简单的链表C++实现
// Aothor: 殷洪
// Date: 2006-06-18
// QQ: 47406310
// Email: 47406310@qq.com

#include <iostream>
#include <stdexcept>
#include <string>

using namespace std;

template <class T> class Node {
public:
Node() {
#ifdef _DEBUG
cout << "Node()" << endl;
#endif
}
~Node() {
#ifdef _DEBUG
cout << "~Node()" << endl;
#endif
}
T data;
Node* next;
};


template <class T> class Iterator {
public:
Iterator() : m_head(0)
, m_curr(0) {}
Iterator(Node<T>* node) : m_head(node)
, m_curr(node) {
#ifdef _DEBUG
cout << "Iterator()" << endl;
#endif
}

~Iterator() {
#ifdef _DEBUG
cout << "~Iterator()" << endl;
#endif
}

bool hasElement() const {
if (!m_curr) {
return false;
}
return true;
}

const T& nextElement() {
T& data = m_curr->data;
m_curr = m_curr->next;
return data;
}
private:
Node<T>* m_head;
Node<T>* m_curr;
};

template <class T> class Link {
public:

Link();
~Link();
void add(const T&);
void remove(const T&);
bool find(const T&);
void clear();
inline bool empty() const { return m_head ? true : false; }
inline Iterator<T> getIterator() const { return Iterator<T>(m_head); }

protected:
void destory();

private:
Node<T>* m_head;
Node<T>* m_curr;
};


template <class T>
Link<T>::Link() :
m_head(0)
, m_curr(0) {
#ifdef _DEBUG
cout << "Link<T>::Link()" << endl;
#endif
}

template <class T>
Link<T>::~Link() {
destory();
#ifdef _DEBUG
cout << "Link<T>::~Link()" << endl;
#endif
}

template <class T>
void Link<T>::add(const T& element) {
if (!(m_head && m_curr)) {
m_head = new Node<T>;
if (!m_head)
throw std::bad_alloc("can't allocate memory!");

m_head->data = element;
m_head->next = 0;
m_curr = m_head;

} else {

Node<T>* node = new Node<T>;
if (!node)
throw std::bad_alloc("can't allocate memory!");

node->data = element;
node->next = 0;

if (m_curr && (0 == m_curr->next)) {
m_curr->next = node;
m_curr = node;
}
}
}

template <class T>
void Link<T>::destory() {
while (m_head) {
Node<T>* next = m_head->next;
delete m_head;
m_head = next;
}
}

template <class T>
void Link<T>::remove(const T& element) {

Node<T>* prev = 0;
Node<T>* ptr = 0;

ptr = m_head;
while (ptr) {
if (m_head->data == element) {
Node<T>* next = m_head->next;
delete m_head;
m_head = next;
break;
}

prev = ptr;
ptr = ptr->next;

if (ptr->data == element) {
prev->next = ptr->next;
delete ptr;
break;
}
}
}

template <class T>
bool Link<T>::find(const T& element) {

Iterator<T> iter = getIterator();
while (iter.hasElement()) {
if (iter.nextElement() == element) {
return true;
}
}
return false;
}

template <class T>
void Link<T>::clear()
{
Iterator<T> iter = getIterator();
while (iter.hasElement()) {
remove(iter.nextElement());
}
}


class Student {
public:
int id;
std::string name;
std::string sex;
std::string remark;

inline bool operator==(const Student& student) const {
return this->id == student.id && this->name == student.name &&
this->sex == student.sex && this->remark == student.remark;
}

inline bool operator!=(const Student& student) const {
return !(*this == student);
}

friend inline ostream& operator<<(ostream& os, const Student& student) {
cout << "-----------class Student-----------" << endl
<< "id: " << student.id <<endl
<< "name: " << student.name << endl
<< "sex: " << student.sex << endl
<< "remark: " << student.remark << endl;
return os;
}
};

typedef struct Message {
Message() {}
Message(const std::string& msg) : msg(msg), len(msg.length()) {}
std::string msg;
size_t len;

inline bool operator==(const Message& msg) const {
return this->len == msg.len && this->msg == msg.msg;
}

inline bool operator!=(const Message& msg) const {
return !(*this == msg);
}

friend inline ostream& operator<<(ostream& os, const Message& msg) {
cout << "-----------struct Message-----------" << endl
<< "msg: " << msg.msg << endl
<< "len: " << msg.len << endl;
return os;
}
} _message_t;

template<typename T>
void printElements(Link<T>& link)
{
Iterator<T>& iter = link.getIterator();
while (iter.hasElement()) {
cout << iter.nextElement();
}
}

void test_student()
{
Link<Student> students;
Student st1;
Student target;

ostringstream oss;
for (int i=0; i<1000; i++) {
st1.id = i;
oss.str("");
oss << "name-" << i;
st1.name = oss.str();

if (i % 2) {
st1.sex = "男";
} else {
st1.sex = "女";
}

oss.str("");
oss << "remark-just soso-" << i;
st1.remark = oss.str();
students.add(st1);
if (12 == i) {
target = st1;
}
}

cout << "all element: " << endl;
printElements(students);

Iterator<Student>& rmvIter = students.getIterator();
int id = 0;
while (rmvIter.hasElement()) {
const Student& rmvElement = rmvIter.nextElement();
if (4 == rmvElement.id) {
students.remove(rmvElement);
}
/*
//delete all elements
if (id == rmvElement.id) {
students.remove(rmvElement);
}
id++;
*/
}

cout.setf(ios_base::boolalpha);
cout << "is empty: " << students.empty() << endl;
cout << "find(xxx): " << students.find(target) << endl;

cout << "remove after:" << endl;
printElements(students);
}

void test_stdstring()
{
Link<std::string> strs;

strs.add("Hello");
strs.add("long");
strs.add("time");
strs.add("see");
strs.add("!!!");

cout << "strs.empty() = " << strs.empty() << endl;
cout << "strs.find(\"!!!\") = " << strs.find("!!!") << endl;
strs.remove("!!!");

Iterator<std::string> strIter = strs.getIterator();
while (strIter.hasElement()) {
cout << strIter.nextElement() << ", ";
}
cout << endl;
}

void test_message()
{
Link<Message> msgs;
msgs.add(Message("Just"));
msgs.add(Message("do"));
msgs.add(Message("it"));
msgs.add(Message("!!!"));

cout << "test_message, find: " << msgs.find(Message("do")) << endl;
printElements(msgs);

msgs.remove(Message("!!!"));
cout << "Message(\"!!!\") removed" << endl;
printElements(msgs);

cout << "Clean all elements" << endl;
msgs.clear();
printElements(msgs);
}
int main(int argc, char* argv[])
{
test_student();
test_stdstring();
test_message();
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值