`
CrazyMizzz
  • 浏览: 24246 次
  • 性别: Icon_minigender_1
  • 来自: 浙江
社区版块
存档分类
最新评论

c++ 用类模版实现链表(c++语言程序设计第四版示例代码)

阅读更多
#include<iostream>
#include<cassert>
using namespace std;
template<class T>
class Node
{
private:
	Node<T> * next;
public:
	T data;                                                                     //数据域

	Node(const T & data, Node<T> * next = 0):data(data),next(next){}            //构造函数
	
	void InsertAfter(Node<T> *p){                                              //在本结点之后出入一个同类结点P
		p->next = next;        //P结点指针域指向当前结点的后继结点
		next = p;              //当前结点的指针域指向P
	}                                       
	
	Node<T> *DeleteAfter(){                                                     //删除本结点的后继结点,并返回其地址
		Node<T>* tempp = next; //将欲删除的结点地址储存到tempp中
		if (next == 0)         //如果当前结点没有后继结点,则反回空指针
			return 0;
		next = tempp->next;    //使当前结点的指针域指向tempp的后继结点
		return tempp;          //返回被删除的结点的地址
	}
	
	Node<T> *NextNode(){ return next; }                                         //获取后继结点的地址
	
	const Node<T>* NextNode()const{ return next; }                              //获取后继结点的地址
	
	~Node(){}
};

template <class T>
class LinkedList {
private:
	// 数据成员:
	Node<T> *front, *rear;      // 表头和表尾指针
	Node<T> *prevPtr, *currPtr; // 记录表当前遍历位置的指针,由插入和删除操作更新
	int size;                   // 表中的元素个数
	int position;               // 当前元素在表中的位置序号。由函数 Reset 使用

	// 函数成员:

	// 生成新结点,数据域为 item,指针域为 ptrNext

	Node<T>* NewNode(const T &item, Node<T> *ptrNext = NULL){
		Node<T> *newNode;

		newNode = new Node<T>(item, ptrNext);

		if (newNode == NULL) {
			cerr << "Memory allocation failure!" << endl;
			exit(1);
		}

		return newNode;
	}

	// 释放结点
	void FreeNode(Node<T> *p){
		delete p;
	}

	// 将链表 L 拷贝到当前表(假设当前表为空)。
	// 被复制构造函数和“operator =”调用
	void Copy(const LinkedList<T> &L){
		if (L.size == 0)
			return;

		front = rear = NewNode(L.front->Data);

		for (Node<T> *srcNode = L.front->NextNode();
			srcNode != NULL;
			srcNode = srcNode->NextNode())
		{
			Node<T> *newNode = NewNode(srcNode->Data);
			rear->InsertAfter(newNode);
			rear = newNode;
		}

		size = L.size;
		Reset(position = L.CurrentPosition());
	}


public:
	//默认构造函数-空
	LinkedList(void): front(NULL), rear(NULL), prevPtr(NULL), currPtr(NULL), size(0), position(0){}
	LinkedList(const LinkedList<T> &L) : front(NULL), rear(NULL), prevPtr(NULL), currPtr(NULL), size(0), position(0){Copy(L);}//复制构造函数
	~LinkedList(void){//析构函数
		Clear();
	}
	LinkedList<T>& operator =(const LinkedList<T> &L){ // 重载赋值运算符
		Clear();
		Copy(L);

		return *this;
	}

	int GetSize(void) const{            // 返回链表中元素个数
		return size;
	}
	bool IsEmpty(void) const{           // 链表是否为空
		return (size == 0);
	}

	/**
	@brief	初始化游标的位置
	@param	pos	从零计起的位置编号
	@note	pos 无限制
	当 pos 在 0 和 size 之间时,prevPtr 和 currPtr 正常指示;
	当 pos 为 0 时,prevPtr = NULL, currPtr = front;
	当 pos 为 size 时,prevPtr = rear, currPtr = NULL;
	当 pos 取其他值时,prevPtr = currPtr = NULL。
	*/
	void Reset(int pos = 0){            // 初始化游标的位置
		if (0 <= pos && pos <= size) {
			position = 0;
			prevPtr = NULL;
			currPtr = front;
			// 游标回到头结点,再逐步前移
			while (pos--)
				Next();
		}
		else {
			position = pos;
			prevPtr = NULL;
			currPtr = NULL;
		}
	}
	void Next(void){                    // 使游标移动到下一个结点
		position++;
		prevPtr = currPtr;

		if (currPtr != NULL)
			currPtr = currPtr->NextNode();
	}
	/**
	@brief	游标是否到了链尾
	@return	游标是否到了链尾
	游标“到了链尾”意即游标“超出了链表”,
	当游标所示的当前结点不存在时即判断到了链尾。
	*/
	bool EndOfList(void) const{     
		return (currPtr == NULL);
	}

	/**
	@brief	返回游标当前的位置
	@return	从零计起的位置编号
	@note	游标可以在链表之外
	*/
	int CurrentPosition(void) const{   
		return position;
	}

	void InsertFront(const T &item){    // 在表头插入结点
		front = NewNode(item, front);

		if (IsEmpty())
			rear = front;

		size++;
		Reset(++position);
	}

	void InsertRear(const T &item){     // 在表尾插入结点
		Node<T> *newNode = NewNode(item);

		if (IsEmpty()) {
			front = rear = newNode;
		}
		else {
			rear->InsertAfter(newNode);
			rear = newNode;
		}

		size++;
		Reset(position);
	}


	/**
	@brief	在当前结点之前插入结点
	@param	item	新结点的数据域
	@note	只考虑当前位置的结点存在的情况
	*/

	void InsertBefore(const T &item){  
		if (currPtr != NULL) {
			Node<T> *newNode = GetNode(item, currPtr);

			if (prevPtr != NULL)
				prevPtr->InsertAfter(newNode);
			else
				front = prevPtr = newNode;

			size++;
			Reset(++position);
		}
	}


	/**
	@brief	在当前结点之后插入结点
	@param	item	新结点的数据域
	@note	只考虑当前位置的结点存在的情况
	*/
	void InsertAfter(const T &item){    
		if (currPtr != NULL) {
			Node<T> *newNode = NewNode(item, currPtr->NextNode());
			currPtr->InsertAfter(newNode);

			if (rear == currPtr)
				rear = newNode;

			size++;
		}
	}

	T DeleteFront(void){                // 删除头结点
		if (IsEmpty()) {
			cerr << "List is empty, delete error." << endl;
			exit(1);
		}

		Node<T> *delNode = front;
		front = front->NextNode();

		if (--size == 0)
			rear = NULL;

		Reset(--position);

		T item = delNode->data;
		FreeNode(delNode);

		return item;
	}

	void DeleteCurrent(void){           // 删除当前结点
		if (currPtr != NULL) {
			if (front == currPtr)
				front = currPtr->NextNode();

			if (rear == currPtr)
				rear = prevPtr;

			if (prevPtr != NULL)
				prevPtr->DeleteAfter();

			FreeNode(currPtr);
			size--;
			Reset(position);
		}
	}

	T& Data(void){                      // 返回对当前结点成员数据的引用
		if (currPtr == NULL) {
			cerr << "Current node is invalid." << endl;
			exit(1);
		}

		return currPtr->data;
	}

	const T& Data(void) const{          // 返回对当前结点成员数据的常引用
		if (currPtr == NULL) {
			cerr << "Current node is invalid." << endl;
			exit(1);
		}

		return currPtr->data;
	}

	// 清空链表:释放所有结点的内存空间。被析构函数和“operator =”调用
	void Clear(void){
		while (!IsEmpty())
			DeleteFront();
	}
};


int main(){
	LinkedList<int> linklist;
	for (int i = 0; i < 10; i++){
		int x;
		cin >> x;
		linklist.InsertFront(x);
	}

	linklist.Reset(0);
	while (!linklist.EndOfList()){
		cout << linklist.Data() << endl;
		linklist.Next();
	}
	cout << endl;
	return 0;
}
分享到:
评论

相关推荐

    C++语言程序设计第四版郑莉

    这本书的第五版是对第四版的更新和完善,旨在跟上C++语言的发展步伐,涵盖最新的C++11、C++14甚至C++17标准。 在C++程序设计中,首先要理解的是C++的基本语法,包括变量声明、数据类型(如整型、浮点型、字符型等)...

    C++语言程序设计第五版郑莉

    《C++语言程序设计第五版》是郑莉教授编著的一本深入介绍C++编程的教材,适合初学者和有经验的程序员进一步提升C++技能。这本书的重点在于讲解C++的基础知识,高级特性以及如何有效地设计和实现程序。在描述中提到的...

    支持类模版的C++双向链表

    总结起来,这个“支持类模版的C++双向链表”示例深入地讲解了C++中的模板机制,包括类模版和函数模版的使用,以及如何结合这些模板技术实现一个通用的双向链表。通过这个示例,我们可以更深入地理解泛型编程,以及...

    链表类 c++ 实现的 链表类 c++ 实现的

    本篇文章将深入探讨如何在C++中实现链表类,并通过具体代码实例来阐述其关键概念。 链表不同于数组,它不连续存储元素,而是通过节点之间的指针链接。每个节点包含两部分:数据部分和指向下一个节点的指针。在C++中...

    C++链表类 模板类

    C++链表类 模板类 #include #include #include "LinkedList.h" using namespace std; template Node&lt;T&gt; *LinkedList&lt;T&gt;::GetNode(const T& item, Node* ptrNext) //生成新结点 { Node&lt;T&gt; *p; p = new Node...

    双向链表模板类简单实现

    本文将深入探讨双向链表及其在C++中的模板类实现,以"双向链表模板类简单实现"为主题,我们来详细了解一下这个话题。 双向链表,与单向链表不同,它的每个节点不仅包含数据,还包含两个指针,一个指向下一个节点...

    c++模板链表类代码

    总结来说,"c++模板链表类代码"涉及了C++的模板技术,通过模板实现了一个泛型的链表类,能够处理不同类型的元素。此外,还涉及到数据结构(链表)的实现,以及可能的自定义类(如`Student`, `People`, `Course`),...

    C++实现链表模板(链表项的数据元素可以为任意类型):链表项的插入、删除、链表的打印、两个链表的连接VS2010

    总结来说,这个项目展示了如何使用C++的类模板来实现一个通用的链表数据结构,以及如何在这之上实现插入、删除、打印和连接链表的基本操作。通过这种方式,我们可以创建一个适用于各种数据类型的链表实现,提高了...

    C++ 链表类模板 清华大牛精心编写

    `15_3.cpp`可能是包含测试用例或示例程序,用于演示如何使用这个链表类模板。 在C++中,链表类模板通常会定义一个节点类(Node)来存储数据和指向下一个节点的指针。例如: ```cpp template struct ListNode { T...

    C++单向链表模板实现

    一个抽象链表类的C++模板实现,主要适合初学者入门数据结构基础。

    实现一个模板类的链表(c++)

    1. 请创建一个数据类型为T的链表类模板List,实现以下成员函数: 1) 默认构造函数List(),将该链表初始化为一个空链表(10分) 2) 拷贝构造函数List(const List&lt;T&gt;& list),根据一个给定的链表构造当前链表(10...

    C++语言程序设计(第3版)清华大学教程

    《C++语言程序设计(第3版)清华大学教程》是一本深入浅出的C++编程教材,由清华大学出版,旨在帮助学生和初学者掌握C++这一强大的编程语言。本教程结合了理论与实践,旨在提升读者的编程能力和问题解决能力。以下是...

    C++实现链表,模板类

    C++实现的模板链表类,没有用到STL的list,是用指针实现的。

    C++模板类——双链表

    使用C++做的双链表模板类 具有头插法,尾插法,左向插入,右向插入,删除结点,获取结点值,设置结点值,复制构造函数,还重载了输出操作符、赋值操作符、相等操作符和不等操作符,还具有倒置链表的功能。还有结点类...

    C++语言程序设计教程(第二版)课件

    C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序设计语言。它的设计融合了模拟器、函数式、面向对象等多种编程范式,使得开发者能够灵活地根据项目需求选择...

    C++栈模版(链表实现)

    下面是一个简单的链表实现的C++栈模版示例: ```cpp #include struct Node { int data; Node* next; }; class Stack { private: Node* top; public: Stack() : top(NULL) {} ~Stack(); void push(int ...

    C++语言程序设计教程电子教案.rar

    这个"C++语言程序设计教程基础教案"是为初学者设计的,旨在帮助他们理解C++的基础知识,包括基本语法、数据类型、控制结构、函数、数组和指针等核心概念。对于初学者来说,掌握这些基础知识是构建复杂程序的基础。 ...

    数据结构与算法分析C++语言描述第四版参考答案

    3. C++编程:此书使用C++语言作为实现数据结构和算法的工具,涵盖了C++的基础知识,如类、对象、模板、STL(标准模板库)、智能指针、异常处理等。通过源代码,读者可以学习如何利用C++的特性来实现高效的数据结构和...

    模板线性表,链表,队列,栈的实现(C++实现)

    本文将深入探讨四个基本数据结构的C++实现:模板线性表、链表、队列和栈。这些数据结构在软件开发中扮演着至关重要的角色,它们提供了多种处理数据的方法,使得算法设计和程序优化变得更加灵活。 1. **模板线性表**...

Global site tag (gtag.js) - Google Analytics