关于数据结构之单链表的C++实现

最近学习了数据结构的一些知识,了解的一下单链表的实现。本文中用类的方式构建节点和链表,未来以后方便使用,直接构建模板类。
首先实现节点的构建

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

	Node()
	{
		next = NULL;
	}

	Node(T element)
	{
		this->element = element;
		next = NULL;
	}
};



之后就是的单链表的类和功能函数,链表类里面设有私有成员有链表头head,链表尾tail,链表长度size。

template<typename T>
class LinkedList
{
public:
	LinkedList();
	~LinkedList();
	void addFirst(T element);
	void addLast(T element);
	T getFirst();
	T getLast();
	T removeFirst();
	T removeLast();
	void add(T element);
	void add(int index, T element);
	void clear();
	T get(int index);
	int indexOf(T element);
	bool isEmpty();
	T removeAt(int index);
private:
	Node<T> *head, *tail;
	int size;
};


接下来实现链表类里的每个功能函数
(1)单链表初始化,构造函数
template<typename T>
LinkedList<T>::LinkedList()
{
	head = tail = NULL;
	size = 0;
}
(2)实现析构函数
template<typename T>
LinkedList<T>::~LinkedList()
{}
(3)插入元素到链表头节点,这里需要注意判断(链表是否为空)尾节点是否为空,如果为空,则将尾节点指向头节点。,size++。
template<typename T>
void LinkedList<T>::addFirst(T element)
{
	Node<T> *newNode = new Node<T>;
	newNode->next = head;
	head = newNode;
	size++;
	if (tail = NULL)
		tail = head;
}
(4)插入元素到链表尾节点,如果链表为空,则把头节点和尾节点一起指向新插入的节点,如果非空,则将尾节点的下一节点指向新插入的节点,然后尾节点再指向尾节点的下一节点,size++。
template<typename T>
void LinkedList<T>::addLast(T element)
{
	if (tail == NULL)
		head = tail = new Node<T>(element);
	else
	{
		tail->next = new Node<T>(element);
		tail = tail->next;
	}
	size++;
}
(5)取链表头元素,增加空链表判断
template<typename T>
T LinkedList<T>::getFirst()
{
	if (size == 0)
		throw runtime_error("Index out of range");
	else
	{
		return head->element;
	}
}
(6)取链表尾节点元素,同样空链表判断
template<typename T>
T LinkedList<T>::getLast()
{
	if (size == 0)
		throw runtime_error("Index out of range");
	else
	{
		return tail->element;
	}
}
(7)移除链表头节点,这里首先进行空链表判断,之后在申请一个临时节点指向头节点,头节点指向头节点的下一个节点,之后返回头节点元素,释放临时节点。
template<typename T>
T LinkedList<T>::removeFirst()
{
	if (head == 0)
		throw runtime_error("No elements in the list");
	else
	{
		Node<T> *temp = head;
		head = head->next;
		if (head == NULL) tail = NULL;
		T element = temp->element;
		size--;
		delete temp;
		return element;
	}
}
(8)删除尾节点,尾节点的删除操作比较麻烦,首先判断是否为空链表,若空,则报错,若为一个元素的链表,申请临时节点指向头节点,之后直接将头节点和尾节点置为NULL。若链表size大于1,那么current指向尾节点的前一个节点,申请临时节点指向尾节点,尾节点指向current节点,tail->next置空,删除临时节点。
template<typename T>
T LinkedList<T>::removeLast()
{
	if (size == 0)
		throw runtime_error("No elements in the list");
	else if (size == 1)
	{
		Node<T> *temp = head;
		head = tail = NULL;
		size = 0;
		T element = temp->element;
		delete temp;
		return element;
	}
	else
	{
		Node<T> *current = head;
		for (int i = 1; i < size - 1; i++)
			curent = current->next;
		Node<T> *temp = tail;
		tail = current;
		tail->next = NULL;
		size--;
		T element = temp->element;
		delete temp;
		return element;
	}
}


(9)指点位置插入节点,先申请标记节点current标记到插入节点的前一节点,之后设置temp为current的下一节点,设置current的下一节点为插入节点。
template<typename T>
void LinkedList<T>::add(int index, T element)
{
	if (index == 0)
		addFirst(element);
	else if (index >= size)
		addLast(element);
	else
	{
		Node<T> *current = head;
		for (int i = 1; i < index; i++)
			current = current->next;
		Node<T> *temp = current->next;
		current->next = new Node<T>(element);
		current->next->next = temp;
		size++;
	}
}



(10)移除指定位置的元素
template<typename T>
T LinkedList<T>::removeAt(int index)
{
	if (index < 0 || index >= size)
		throw runtime_error("Index out of range");
	else if (index == 0)
		removeFirst();
	else if (index = size - 1)
		removeLast();
	else
	{
		Node<T> *previous = head;
		for (int i = 1; i < index; i++)
		{
			previous = previous->next;
		}
		Node<T> *temp = previous->next;
		previous->next = temp->next;
		size--;
		T element = temp->next;
		delete temp;
		return element;
	}
}


阅读更多
上一篇学习递归典型例子的一些心得
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭