很早以前写的一个例子,简单的模仿STL实现一个链表。我想对于想使用C++写一个简单链表的初学者有帮助 !
////////////////////////////////////////////////////////////////////////////////
// 简单的链表C++实现
// Aothor: 殷洪
// Date: 2006-06-18
// QQ: 47406310
// Email: 47406310@qq.com
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#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&);
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;
}
typedef struct Student {
int id;
std::string name;
std::string sex;
std::string remark;
} _student_t;
inline bool operator==(const _student_t& st1, const _student_t& st2) {
return st1.id == st2.id && st1.name == st2.name &&
st1.sex == st2.sex && st1.remark == st2.remark;
}
inline bool operator!=(const _student_t& st1, const _student_t& st2) {
return !(st1 == st2);
}
void printElements(Link<_student_t>& link)
{
Iterator<_student_t>& iter = link.getIterator();
while (iter.hasElement()) {
const _student_t& s = iter.nextElement();
cout << "id = " << s.id << ", "
<< "name = " << s.name << ", "
<< "sex = " << s.sex << ", "
<< "remark = " << s.remark << endl;
}
}
int main(int argc, char* argv[])
{
Link<_student_t> students;
_student_t st1;
_student_t target;
char temp[255];
for (int i=0; i<15; i++) {
st1.id = i;
sprintf(temp, "name-%d", i);
st1.name = temp;
if (i % 2) {
st1.sex = "男";
} else {
st1.sex = "女";
}
sprintf(temp, "remark-just soso-%d", i);
st1.remark = temp;
students.add(st1);
if (12 == i) {
target = st1;
}
}
cout << "all element: " << endl;
printElements(students);
Iterator<_student_t>& rmvIter = students.getIterator();
int id = 0;
while (rmvIter.hasElement()) {
const _student_t& 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);
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;
return 0;
}
分享到:
相关推荐
这个Demo的源代码对于初学者而言是一份宝贵的教育资源,它展示了C++ Builder开发游戏的基本流程和技巧,同时也揭示了游戏开发中的一些通用策略和问题解决方案。 总结,C++ Builder纸牌游戏Demo v0.05项目是一个...
通用性是通过使用void指针或者模板(如果使用C++)来实现的,这样可以将任何类型的指针存储为节点的数据。 在描述中提到的"使用"部分,可能包括了如何创建链表、添加元素、删除元素、遍历链表以及查找特定元素等...
1. **编程语言**:Demo源码通常是用某种编程语言编写的,如Java、Python、C++、JavaScript等。不同的编程语言有不同的语法和特性,理解Demo的源码有助于深入学习和掌握相应语言。 2. **编程结构**:源码通常遵循...
3. **列表(List)**:`std::list`是双向链表,允许在任意位置快速插入和删除元素,但随机访问效率较低。 4. **双端队列(Deque)**:`std::deque`类似于一个双端的动态数组,支持两端的快速插入和删除,以及随机...
在C++中,MFC库提供了一个名为CList的模板类,它为开发者提供了便捷的方式来实现链表操作。CList支持泛型编程,可以存储任何类型的对象。CList类包含了添加元素(AddHead, AddTail)、遍历元素(GetFirst, GetNext)...
这个例子就是查询任何可执行文件的版本信息并且 C++builder 和 VC 都通用,只需要把 AnsiString 替换成 CString 就行了。 gh0st v3.6 源码 - 可下断点调试! 如题。详细见源码。 GMem 内存管理单元源码。GMem.cpp...
1. **数据结构**:这是编程的基础,包括数组、链表、栈、队列、哈希表、树(二叉树、红黑树等)、图等。理解它们的特性、操作和应用场景是至关重要的。 2. **算法**:排序(快速排序、归并排序、堆排序等)、搜索...
算法是处理容器中数据的通用方法,如排序、查找等;函数对象是具有操作行为的对象,常用于算法中。 ### 二、一维向量(vector) 1. **创建与初始化**:通过`std::vector<T> vec;`声明一个空的向量,其中T是元素...
标签为空,压缩包子文件的文件名称"Parallel-Sauce-Demo-main"同样没有提供足够的线索来确定这是一个关于什么技术或主题的资料。通常,"main"可能指的是项目的主目录,但没有更多的上下文,我们无法深入讨论。 不过...
通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出...