简述
前面用c写的链表主要使用泛型指针(void *)存储数据的地址,索引到不同类型的数据,而用C++类模板实现后可以直接存储数据,编译器会根据定义好的数据类型动态分配空间。
实现
//链表节点
template<class T>
class LinkNode
{
public:
T data;
LinkNode<T> *next;
};
//链表
template <class T>
class LinkList
{
public:
//初始化
LinkList();
//指定位置插入元素
void insert_LinkList(int pos, T val);
//头部插入
void Fush_Front(T val);
//尾部插入
void Fush_Back(T val);
//指定位置删除
void RemoveByPos_LinkList(int pos);
//头删
void Pop_Front();
//尾删
void Pop_Back();
//获得链表大小
int size_LinkList();
//根据指定位置获得数据
T data_LinkList(int index);
//值删除
void RemoveByVal(T val);
//遍历链表
void Show_LinkList(void(*MyPrint)(T val));
//析构函数
~LinkList();
private:
LinkNode<T> mHeader;
int mSize;
};
//初始化
template <class T>
LinkList<T>::LinkList()
{
this->mHeader.next = NULL;
this->mSize = 0;
}
//指定位置插入元素
template <class T>
void LinkList<T>::insert_LinkList(int pos, T val)
{
if (pos < 0 || pos > this->mSize)
{
pos = this->mSize;
}
//创建新节点
LinkNode<T>* newnode = new LinkNode<T>;
newnode->data = val;
newnode->next = NULL;
//辅助指针
LinkNode<T>* current = &(this->mHeader);
for (int i = 0; i < pos; i++)
{
current = current->next;
}
//新节点入链表
newnode->next = current->next;
current->next = newnode;
this->mSize++;
}
//头部插入
template <class T>
void LinkList<T>::Fush_Front(T val)
{
insert_LinkList(0, val);
}
//尾部插入
template <class T>
void LinkList<T>::Fush_Back(T val)
{
insert_LinkList(this->mSize, val);
}
//指定位置删除
template <class T>
void LinkList<T>::RemoveByPos_LinkList(int pos)
{
if (this->mSize == 0)
{
return;
}
if (pos < 0 || tpos > this->mSize)
{
pos = this->mSize;
}
//找到被删除节点的前一个节点
LinkNode<T>* current = &(this->mHeader);
for (int i = 0; i < pos; i++)
{
current = current->next;
}
//缓存被删除节点
LinkNode<T>* pDel = current->next;
//建立新的前后驱关系
current->next = current->next->next;
//释放被删除节点
delete pDel;
this->mSize--;
}
//头删
template <class T>
void LinkList<T>::Pop_Front()
{
if (this->mSize == 0)
{
return;
}
RemoveByPos_LinkList(0);
}
//尾删
template <class T>
void LinkList<T>::Pop_Back()
{
if (this->mSize == 0)
{
return;
}
RemoveByPos_LinkList(this->mSize - 1);
}
//获得链表大小
template <class T>
int LinkList<T>::size_LinkList()
{
return this->mSize;
}
//获得数据
template <class T>
T LinkList<T>::data_LinkList(int index)
{
if (this->mSize == 0)
{
return -1;
}
if (index < 0 || index >= this->mSize)
{
return -1;
}
LinkNode<T>* current = &(this->mHeader);
for (int i = 0; i < index; i++)
{
current = current->next;
}
return current->data;
}
//值删除
template <class T>
void LinkList<T>::RemoveByVal(T val)
{
if (this->mSize == 0)
{
return;
}
//辅助指针变量
LinkNode<T>* prev = &(this->mHeader);
LinkNode<T>* current = prev->next;
while (current != NULL)
{
if (current->data == val)
{
prev->next = current->next;
delete current;
this->mSize--;
break;
}
prev = current;
current = current->next;
}
}
//遍历链表
template <class T>
void LinkList<T>::Show_LinkList(void(*MyPrint)(T val))
{
if (this->mSize == 0)
{
return;
}
LinkNode<T>* current = this->mHeader.next;
while (current != NULL)
{
MyPrint(current->data);
current = current->next;
}
}
//析构函数
template <class T>
LinkList<T>::~LinkList()
{
cout << "调用析构函数" << endl;
LinkNode<T>* current = this->mHeader.next;
while (current != NULL)
{
LinkNode<T>* pNext = current->next;
delete current;
current = pNext;
}
}