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