#include<iostream>
using naemspace std;
template<typename T>
struct Node //定义结点结构体
{
T data; //数据域
Node<T> *next; //指针域
};
template<typename T>
class LinkList
{
public:
Node<T> *first; //带有头结点的链表
private:
LinkList();//无参构造
LinkList(T a[], int n); //有参构造,建立长的为n的单链表
~LinkList(); //析构函数
int GetLength(); //求长度
void Insert(int i, T x); //插入操作,在位置i插入元素x
T Get(int i); //按位查找,在单链表中找到位置i的元素并返回
int GetLocate(T x); //按值查找,在单链表中找到值为x的元素并返回其位置
void PrintList(); //遍历打印
T Delete(int i); //删除操作,删除i位置对应元素并返回其值
bool Empty(); //判空
};
//无参构造的实现
template<typename T>
LinkList<T>::LinkList(){}
//有参构造的实现
//单链表建立分两种,一种为头插法,一种为尾插法
//首先实现头插法
template<typename T>
LinkList<T>::LinkList(T a[], int n)
{
first = new Node<T>;
first->next = nullptr;
for(int i = 0;i < n;i++)
{
Node<T> *p = nullptr;
p = new Node<T>; //此句可有可无,是为了给p申请空间?
p->data = a[i];
p->next = first->next;
first = p; //因为是头插法,插进来的p一直作为头结点进入链表
}
}
//然后尾插法实现
template<typename T>
LinkList<T>::LinkList(T a[], int n)
{
Node<T> *r = first;
Node<T> *p = nullptr;
for(int i = 0;i < n;i++)
{
p = new Node<T>;
p->data = a[i];
r->next = p; //在头指针之后顺序插入
r = p; //r指针依次后移,在尾部插入p
}
r->next = nullptr; //单链表建立完毕后,最后一个结点的指针域为空
}
//析构函数
template<typename T>
LinkList<T>::~LinkList()
{
Node<T> *p = first;
while(first != nullptr)
{
first = first->next;
delete p;
p = first; //通过移动头指针实现删除
}
}
//求长度操作
template<typename T>
int GetLength()
{
Node<T> *p = first->next;
int count = 0;
while(p != nullptr)
{
count++;
p = p->next;
}
}
//插入操作
template<typename T>
void LinkList<T>::Insert(int i, T x)
{
int count = 0; //从first开始所以count从0开始计数
Node<T> *p = first; //因为要考虑空链表的情况所以p指向first而不是first->next
while(p != nullptr && count < i-1)
{
count++;
p = p->next;
} //需找到要插入元素的钱一个位置,所以count<i-1,
//当循环终止时count = i-1
if(p == nullptr) throw"插入位置错误";
Node<T> *s = nullptr;
s = new Node<T>;
s->data = x;
s->next = p->next;
p->next = s;
}
//按位查找
template<typename T>
T LinkList<T>::Get(int i)
{
Node* p = first->next;
int count = 1;
while(p != nullptr && count < i)
{
count++;
p = p->next;
}
if(p == nullptr) throw"查找位置错误!";
else return p->data;
}
//按值查找
template<typename T>
int LinkList<T>::GetLocat(T x)
{
Node<T> *P = first->next;
int count = 1; //记录下标
while(p != nullptr)
{
if(p->data == x) return count;
p = p->next;
count++;
}
return 0; //此句容易忘记
}
//遍历打印
template<typename T>
void LinkList<T>::PrintList()
{
Node<T> *p = first->next;
if(p == nullptr) throw"链表为空!";
while(p != nullptr)
{
cout<< p->data << " ";
p = p->next;
}
cout<<endl;
}
//删除操作
template<typename T>
T LinkList<T>::Delete(int i)
{
Node<T> *p = first;
int count = 0;
while(p != nullptr && count < i-1)
{
count++;
p = p->next;
} //找到要删除位置的前一个位置
if(p == nullptr || p->next == nullptr) throw"删除位置错误!";
else
{
Node<T> *s = nullptr;
s = new Node<T>;
s = p->next; //借s记录p的下一个结点
T x = p->data; //记录p位置的数据元素
p->next = s->next; //将s结点从链中摘除,实现“摘链”
delete s;
return x;
}
}
//判空操作
template<typename T>
bool LinkList<T>::Empty()
{
if(first->next == nullptr) return true;
return false;
}
在运用Node时总是忘记定义类型<T>
只是写了单链表的类模板,没有主函数实现