之前写的那个重载的是全局的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;
}
分享到:
相关推荐
本话题主要关注的是Java中的链表实现,特别是循环链表的模板类设计。循环链表与普通链表的主要区别在于最后一个节点指向了头节点,形成一个闭合的环,这在处理循环遍历或某些特定算法时非常方便。 首先,让我们详细...
例如,`java.io`包提供了文件操作和流处理功能,`java.util`包中的`ArrayList`和`HashMap`是常用的集合类,`java.net`包则处理网络通信。Java API的设计理念强调了“一次编写,到处运行”,理解其工作原理有助于写出...
5. **集合框架**:Java集合框架包括接口(如List、Set、Map)和实现类,提供了一套完善的存储和操作数据的工具。 6. **反射机制**:Java的反射机制可以在运行时检查类的信息,动态创建对象和调用方法。 这些编程...
对于Java实现,可以利用Java集合框架中的接口,如List或Map,来简化数据结构的实现。例如,每个节点可以是一个HashMap,键是键值,值是子节点。而C++实现中,可以使用STL容器,如std::vector或std::map,作为节点的...
多态则允许我们定义通用接口,使得不同类型的对象可以对同一消息作出不同的响应,提高了程序的灵活性。 C++基础部分通常包括基本语法、控制结构、函数、数组和字符串等。理解如何声明和初始化变量,以及如何使用...
1. **基础语法**:与C++类似,Java也有其基本语法,如变量、数据类型、运算符和控制流语句。 2. **类与对象**:Java同样基于面向对象,但它的类和对象模型更为严格,有接口和抽象类的概念。 3. **封装、继承与多态**...
这篇资料集合了50个经典的C++和Java编程题目,是学习和提升编程技能的宝贵资源。涵盖了C++和Java的基础语法、算法以及数据结构等多个重要领域,对于初学者和有一定经验的开发者来说,都是很好的实践平台。下面,我将...
### 以C++, Java, C#, 和B#进行类设计的基本原理 #### 数据抽象:一种演进 在软件工程领域,随着面向对象编程语言的发展,数据抽象成为了构建可重用软件组件的核心技术之一。本章节将详细介绍数据抽象的概念及其...
8. **容器与集合框架**:Java的集合框架(如ArrayList、LinkedList、HashMap等)提供了丰富的数据存储和操作功能,而C++的STL(标准模板库)中的容器(如vector、list、map等)同样如此。 9. **内存管理**:C++需要...
此外,书中还扩展了对Java中的Deque接口和LinkedList类的讨论,增加了对Java集合框架中条目对象的覆盖范围,并且将所有代码片段API与泛型类型完全集成。作者还加入了关于可导航映射接口(NavigatableMap)以及在Java...
C++和Java都提供了丰富的库函数和内置机制来优化算法实现,比如C++的STL(Standard Template Library)和Java的集合框架。 此外,LeetCode的解题过程也是学习如何写出清晰、可读性强的代码的好机会。良好的代码风格...
在IT行业中,面试和笔试是求职者通往心仪职位的关键步骤...以上就是压缩包中可能涉及的C/C++和Java面试笔试知识点,以及一些通用的面试和笔试技巧。通过深入理解和熟练掌握这些内容,可以大大提高求职者的面试成功率。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 13、&和&&的区别。 &是位运算符...
- **语法**:Java语法与C++类似,但更简洁。学习Java首先要了解基本的变量、数据类型、运算符、流程控制语句(如if-else,switch,for,while等)。 - **类与对象**:Java是一种面向对象的语言,理解类的定义、...
1. **模板简介**:模板是C++的一个强大特性,它允许创建通用的函数或类。通过模板,可以编写能够处理不同类型数据的代码,极大地提高了代码的复用性。 #### 二十、标准模板库(STL) 1. **概述**:STL(Standard ...
7. **扩展了双端队列接口Deque和链表类LinkedList的讨论**:详细介绍了这两个数据结构的特性和用法。 8. **增多了关于Java集合框架中条目对象的覆盖内容**:包括了更多的示例和应用场景。 9. **全面集成了代码片段...
再者,Java集合框架是处理数据的重要工具,包括List、Set、Map等接口及其实现类。ArrayList和LinkedList分别是动态数组和链表实现的列表,HashSet和HashMap则提供了无序且不重复元素的存储。此外,接口如Iterable和...
Java集合框架是处理对象组的重要工具,包括List、Set和Map接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。它们提供了灵活的数据存储和检索机制,支持各种数据结构,如数组、链表、树等。 异常处理是...
Java集合框架提供了实现特定数据结构的接口和类。 **Set接口**:不允许重复元素。 **List接口**:有序且允许重复元素。 **Map接口**:存储键值对映射关系。 **Set接口** - **HashSet**:基于哈希表实现,元素...