单链表:
优点:能够在插入以及删除的时候有较低的时间复杂度,且不需要进行预先的空间分配,不会造成溢出
缺点:不能方便存取数据,存取速度慢,且为了两节点之间的逻辑关系付出了额外的空间代价
(不仅要存数据,还有link需要存储)
单链表的类定义:
注意:在一开始需要先定义一个节点类方便操作
template<class T>
struct LinkNode
{
T data;
LinkNode<T>* link;
LinkNode(LinkNode<T>* ptr=NULL) { link = ptr; }
LinkNode( T item, LinkNode<T>* ptr=NULL) { link = ptr; data = item; }
};
template<class T>
class List {
protected:
LinkNode<T>* first;//注意这里的first是附加头节点,没有实际值,起指示作用
public:
List() { first = new LinkNode<T>; }
List(const T& x) { first = new LinkNode<T>(x); }
List(List<T>& L);
~List() { makeEmpty(); }
void makeEmpty();
int Length()const;
LinkNode<T>* getHead()const { return first; }
LinkNode<T>* search(T& x)const;
LinkNode<T>* locate(int i);
bool getData(int i, T& x)const;
void setData(int i, T& x);
bool insert(int i, T& x);
bool remove(int i, T& x);
bool isEmpty() { return first->link == NULL; }
void input();
void output();
};
在声明函数
LinkNode( T item, LinkNode<T>* ptr=NULL) { link = ptr; data = item; }
后,要声明一个带有初始值的节点为以下代码
LinkNode<T>* q=new LinkNode<T>(x);//必须使用new函数
不要和拷贝构造函数(如下错误)弄混了
LinkNode<T>* q(x);
一般单链表使用带有附加头节点的形式,保证在空表的情况下易于对数据进行处理,不用担心把首节点去掉后整个链表被删了
template<class T>
void List<T>::makeEmpty()
{
while (first->link != NULL)
{
LinkNode<T>* p=first->link;
delete first;
first = p;
}
delete first;
}
在进行析构时,注意不要直接删除first节点,这样无法获得后面的节点进而无法删除,会一直占用内存,不利于计算机健康故应采用以上方法逐个删除
在进行删除操作时注意要到要删除的节点的前一个,然后进行删除
p->link=p->link->link;
但是注意原本的p->link还要进行删除
代码如下
template<class T>
bool List<T>::remove(int i,T&x)
{
if (i <= 0)return false;
int count = 0;
LinkNode<T>* p = first->link;
while (p != NULL)
{
count++;
if (count == i - 1)
break;
p = p->link;
}
if (p == NULL)return false;
LinkNode<T>* q = p->link;
x = q->data;
p->link = q->link;
delete q;
return true;
}
总的代码如下:
#include<iostream>
using namespace std;
template<class T>
struct LinkNode
{
T data;
LinkNode<T>* link;
LinkNode(LinkNode<T>* ptr=NULL) { link = ptr; }
LinkNode( T item, LinkNode<T>* ptr=NULL) { link = ptr; data = item; }
};
template<class T>
class List {
protected:
LinkNode<T>* first;//注意这里的first是头指针
public:
List() { first = new LinkNode<T>; }
List(const T& x) { first = new LinkNode<T>(x); }
List(List<T>& L);
~List() { makeEmpty(); }
void makeEmpty();
int Length()const;
LinkNode<T>* getHead()const { return first; }
LinkNode<T>* search(T& x)const;
LinkNode<T>* locate(int i);
bool getData(int i, T& x)const;
void setData(int i, T& x);
bool insert(int i, T& x);
bool remove(int i, T& x);
bool isEmpty() { return first->link == NULL; }
void input();
void output();
};
template<class T>
List<T>::List(List<T>& L)
{
LinkNode<T>*p=first;
LinkNode<T>* q=L.first;
while (q->link!= NULL)
{
LinkNode<T>* temp(q->link->data);
p->link = temp;
q = q->link;
p = p->link;
}
}
template<class T>
void List<T>::makeEmpty()
{
while (first->link != NULL)
{
LinkNode<T>* p=first->link;
delete first;
first = p;
}
delete first;
}
template<class T>
int List<T>::Length()const {
int i = 0;
LinkNode<T>* p=first;
while (p->link != NULL)
{
++i;
p = p->link;
}
return i;
}
template<class T>
LinkNode<T>* List<T>::search(T& x)const
{
LinkNode<T>* p=first->link;
while (p != NULL)
{
if (p->data == x)
break;
else
p = p->link;
}
return p;
}
template<class T>
LinkNode<T>* List<T>::locate(int i)
{
int count = 0;
LinkNode<T>* p=first->link;
while (p != NULL)
{
count++;
if (count == i)
break;
p = p->link;
}
return p;
}
template<class T>
bool List<T>::getData(int i ,T&x)const
{
if (i <= 0)return false;
int count = 0;
LinkNode<T>* p=first->link;
while (p != NULL)
{
count++;
if (count == i)
break;
p = p->link;
}
if (p == NULL)return false;
x = p->data;
return true;
}
template<class T>
void List<T>::setData(int i,T&x)
{
if (i <= 0)return ;
int count = 0;
LinkNode<T>* p=first->link;
while (p != NULL)
{
count++;
if (count == i)
break;
p = p->link;
}
p->data = x;
}
template<class T>
bool List<T>::insert(int i, T& x)
{
if (i <= 0)return false;
int count = 0;
LinkNode<T>* p=first->link;
while (p != NULL)
{
count++;
if (count == i-1)
break;
p = p->link;
}
if (p == NULL)return false;
LinkNode<T>* q=new LinkNode<T>(x);
LinkNode<T>* r=p->link;
q->link = r;
p->link = q;
return true;
}
template<class T>
bool List<T>::remove(int i,T&x)
{
if (i <= 0)return false;
int count = 0;
LinkNode<T>* p = first->link;
while (p != NULL)
{
count++;
if (count == i - 1)
break;
p = p->link;
}
if (p == NULL)return false;
LinkNode<T>* q = p->link;
x = q->data;
p->link = q->link;
delete q;
return true;
}
template<class T>
void List<T>::input()
{
int count = 0;
cout << "请输入链表初始大小" << endl;
cin >> count;
cout << "请输入每一个值" << endl;
LinkNode<T>* p = first;
while (count--)
{
T temp; cin >> temp;
LinkNode<T>* q=new LinkNode<T>(temp);
p->link = q;
p = p->link;
}
}
template<class T>
void List<T>::output()
{
LinkNode<T>* p = first->link;
while (p != NULL)
{
cout << p->data << " ";
p = p->link;
}
}