数据结构-单链表-【C++模板实现】

本文介绍了一个使用C++模板实现的链表类,包括插入、删除等基本操作,并提供了完整的源代码示例。

Node.h

#pragma once
#include<iostream>

using namespace std;

template<class T>
class Node
{
public:
	T data;
	Node<T> * next;

	Node():next(NULL) {}

	Node(T value):next(NULL),data(value) {}

	~Node() {}

	friend ostream& operator<<(ostream &os, const Node<T> *node)
	{
		os << node->data;
		return os;
	}
};

List.h

#pragma once
#include"Node.h"
//链表顺序与数组顺序一致,从0开始计算第一个有数据域的节点

template<class T>
class List
{
public:
	List();
	~List();
	void ClearList();
	bool ListEmpty();
	int ListLength();
	T& GetElem(int i);//返回第i节点数据
	int LocateElem(T value);//定位数据与pNode->data一致节点的位置,若没有则返回-1
	void ListTraverse();
	bool ListInsert(int i, T value);//将value插入第i个节点之前
	bool ListDelete(int i);//删除第i个节点
	bool ListInsertHead(T value);
	bool ListInsertTail(T value);

private:
	Node<T> *m_pList;
	int m_iLength;
};

List.cpp

#include"List.h"
#include<iostream>

using namespace std;

template<class T>
List<T>::List()
{
	m_pList = new Node<T>;

	m_iLength = 0;
}

template<class T>
List<T>::~List()
{
	ClearList();
	delete m_pList;
}

template<class T>
void List<T>::ClearList()
{
	for(int i=0;i<m_iLength;i++)
		ListDelete(i);

	m_pList->next = NULL;
	m_iLength = 0;
}

template<class T>
bool List<T>::ListEmpty()
{
	return !m_iLength;
}

template<class T>
int List<T>::ListLength()
{
	return m_iLength;
}

template<class T>
bool List<T>::ListInsertHead(T value)
{
	//new一个Node
	Node<T> *newNode = new Node<T>(value);

	//将newNode连接至头节点
	newNode->next = m_pList->next;
	m_pList->next = newNode;

	m_iLength++;
	return true;
}

template<class T>
bool List<T>::ListInsertTail(T value)
{
	//new一个Node,将newNode->next置为NULL
	Node<T> *newNode = new Node<T>(value);


	//找到尾节点currentNode
	Node<T> *currentNode = m_pList;
	while (currentNode->next != NULL)
		currentNode = currentNode->next;

	//将newNode连接上尾节点currentNode
	currentNode->next = newNode;
	
	m_iLength++;
	if(newNode->next == NULL)
		return true;
	else return false;
}

template<class T>
bool List<T>::ListInsert(int i, T value)//在第i节点之前插入node
{
	if (i<0 || i>m_iLength) return false;

	//先找到需要插入的i节点之前的节点currentNodeBefore
	Node<T> *currentNodeBefore = m_pList;
	for(int k=0;k<i;k++)
		currentNodeBefore = currentNodeBefore->next;

	//new一个Node
	Node<T> * newNode = new Node<T>(value);

	//将newNode插入currentNodeBefore之后,即为插入i节点前
	newNode->next = currentNodeBefore->next;
	currentNodeBefore->next = newNode;

	m_iLength++;
	return true;
}

template<class T>
bool List<T>::ListDelete(int i)
{
	if (i<0 || i>=m_iLength) return false;

	//找到需要删除节点的前一个节点
	Node<T> *currentNodeBefore = m_pList;
	for (int k = 0; k < i; k++)
		currentNodeBefore = currentNodeBefore->next;

	//定位currentNode,删除操作
	Node<T> *currentNode = currentNodeBefore->next;
	currentNodeBefore->next = currentNodeBefore->next->next;

	delete currentNode;

	m_iLength--;
	return true;
}

template<class T>
T& List<T>::GetElem(int i)
{
	if (i < 0 || i >= m_iLength)
		cout << "A wrong position!\n";


	Node<T> *currentNode = m_pList->next;
	for (int k = 0; k < i; k++)
		currentNode = currentNode->next;

	return currentNode->data;
}

template<class T>
int List<T>::LocateElem(T value)
{
	Node<T> *currentNode = m_pList->next;
	for (int k = 0; k < m_iLength; k++)
	{
		if (currentNode->data == value)
			return k;
		currentNode = currentNode->next;
	}
	return -1;
}

template<class T>
void List<T>::ListTraverse()
{
	cout << "Node size: " << m_iLength << endl;
	Node<T> *currentNode = m_pList->next;
	while (currentNode != NULL)
	{
		cout << currentNode << " ";
		currentNode = currentNode->next;
	}
	cout << endl;
}

main.cpp

#include"List.h"
#include"List.cpp"
#include<iostream>

using namespace std;

int main()
{

	List<int> *pList = new List<int>();

	pList->ListInsertTail(1);
	pList->ListInsertTail(6);
	pList->ListInsertTail(8);
	pList->ListInsertTail(9);
	pList->ListInsertTail(13);


	pList->ListTraverse();


	delete pList;
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值