`
cppmuleeye
  • 浏览: 1323 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

C++简单的通用链表Demo

阅读更多

很早以前写的一个例子,简单的模仿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;
}

 

分享到:
评论
4 楼 sdkjsdj 2010-01-22  
看起来写的还是不错的。但是有可能还欠缺一点功底。要不然啊你去看看其他人写的。
3 楼 tangfeng 2010-01-09  
这叫什么通用啊,你应该看看Linux里面的那个链表,那才经典!
2 楼 ph4nut 2010-01-02  
因為重載操作符== !== 里面是用具體的sex,id等等來做判斷,所以不具有通用性。
1 楼 gexialover 2009-10-26  
这是单链表,不是通用链表!

相关推荐

    C++ Builder纸牌游戏Demo v0.05项目完整源代码带扑克牌图片

    这个Demo的源代码对于初学者而言是一份宝贵的教育资源,它展示了C++ Builder开发游戏的基本流程和技巧,同时也揭示了游戏开发中的一些通用策略和问题解决方案。 总结,C++ Builder纸牌游戏Demo v0.05项目是一个...

    链表-LinkList-包含测试demo和makefile

    通用性是通过使用void指针或者模板(如果使用C++)来实现的,这样可以将任何类型的指针存储为节点的数据。 在描述中提到的"使用"部分,可能包括了如何创建链表、添加元素、删除元素、遍历链表以及查找特定元素等...

    程序Demo源码 程序Demo源码

    1. **编程语言**:Demo源码通常是用某种编程语言编写的,如Java、Python、C++、JavaScript等。不同的编程语言有不同的语法和特性,理解Demo的源码有助于深入学习和掌握相应语言。 2. **编程结构**:源码通常遵循...

    C++精选代码库。包含常用STL容器模拟实现、algorithm算法头文件函数demo

    3. **列表(List)**:`std::list`是双向链表,允许在任意位置快速插入和删除元素,但随机访问效率较低。 4. **双端队列(Deque)**:`std::deque`类似于一个双端的动态数组,支持两端的快速插入和删除,以及随机...

    链表初学者指南

    在C++中,MFC库提供了一个名为CList的模板类,它为开发者提供了便捷的方式来实现链表操作。CList支持泛型编程,可以存储任何类型的对象。CList类包含了添加元素(AddHead, AddTail)、遍历元素(GetFirst, GetNext)...

    vc++ 开发实例源码包

    这个例子就是查询任何可执行文件的版本信息并且 C++builder 和 VC 都通用,只需要把 AnsiString 替换成 CString 就行了。 gh0st v3.6 源码 - 可下断点调试! 如题。详细见源码。 GMem 内存管理单元源码。GMem.cpp...

    offer-demo-2

    1. **数据结构**:这是编程的基础,包括数组、链表、栈、队列、哈希表、树(二叉树、红黑树等)、图等。理解它们的特性、操作和应用场景是至关重要的。 2. **算法**:排序(快速排序、归并排序、堆排序等)、搜索...

    STL tutorial

    算法是处理容器中数据的通用方法,如排序、查找等;函数对象是具有操作行为的对象,常用于算法中。 ### 二、一维向量(vector) 1. **创建与初始化**:通过`std::vector&lt;T&gt; vec;`声明一个空的向量,其中T是元素...

    平行酱演示:Frank平行酱演示

    标签为空,压缩包子文件的文件名称"Parallel-Sauce-Demo-main"同样没有提供足够的线索来确定这是一个关于什么技术或主题的资料。通常,"main"可能指的是项目的主目录,但没有更多的上下文,我们无法深入讨论。 不过...

    超级有影响力霸气的Java面试题大全文档

    通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。 11、EJB是基于哪些技术实现的?并说出...

Global site tag (gtag.js) - Google Analytics