一、chain.h(普通链表类)
</pre><pre name="code" class="cpp">/*///
链表类Chain
///*/
#pragma once
#include<iostream>
#include"xcept.h"
using namespace std;
template<class T> class Chain;
template <class T>class ChainNode
{
friend Chain<T>;
private:
T data;
ChainNode<T> *link;
};
template<class T>class Chain
{
public:
Chain()
{
first = 0;
}
~Chain();
bool IsEmpty() const
{
return first == 0;
}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain<T>& Delete(int k, T& x);
Chain<T>& Insert(int k, const T& x);
void Output(ostream& out) const;
private:
ChainNode<T> *first; // 指向第一个节点的指针
};
template<class T>Chain<T>::~Chain()
{
// 链表的析构函数,用于删除链表中的所有节点
ChainNode<T> *next; // 下一个节点
while (first)
{
next = first->link;
delete first;
first = next;
}
}
template<class T>int Chain<T>::Length() const
{
// 返回链表中的元素总数
ChainNode<T> *current = first;
int len = 0;
while (current)
{
len++;
current = current->link;
}
return len;
}
template<class T>bool Chain<T>::Find(int k, T& x) const
{
/* 寻找链表中的第 k 个元素,并将其传送至 x
如果不存在第 k 个元素,则返回 false,否则返回 true */
if (k<1)
return false;
ChainNode<T> *current = first;
int index = 1; // current的索引
while (index < k && current)
{
current = current->link;
index++;
}
if (current) // 如为 NULL,则链表没有 k 个元素(提前结束)
{
x = current->data;
return true;
}
return false; // 不存在第 k 个元素
}
template<class T>int Chain<T>::Search(const T& x) const
{
/* 寻找 x,如果发现 x,则返回 x 的地址
如果 x 不在链表中,则返回 0 */
ChainNode<T> *current = first;
int index = 1; // current的索引
// 假定对于类型 T 定义了 != 操作
while (current && current->data != x)
{
current = current->link;
index++;
}
if (current)
return index;
return 0;
}
template<class T>void Chain<T>::Output(ostream& out) const
{
// 将链表元素送至输出流
ChainNode<T> *current;
for (current = first; current; current = current->link)
out << current->data << " ";
}
// 重载<<(对类型 T 定义 << 操作)
template <class T>ostream& operator<<(ostream& out, const Chain<T>& x)
{
x.Output(out);
return out;
}
template<class T>Chain<T>& Chain<T>::Delete(int k, T& x)
{
// 把第 k 个元素取至 x,然后从链表中删除第 k 个元素
// 如果不存在第 k 个元素,则引发异常 OutOfBounds
if (k < 1 || !first)
throw OutOfBounds(); // 不存在第 k 个元素
// p 最终将指向第 k 个节点
ChainNode<T> *p = first;
// 将 p 移动至第 k 个元素,并从链表中删除该元素
if (k == 1) // p 已经指向第 k 个元素
first = first->link; // 删除之
else
{
// 用 q 指向第 k-1 个元素
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q; index++)
q = q->link;
if (!q || !q->link) // 无第 k 个元素(q 只到 k-1 个)
throw OutOfBounds();
p = q->link; // 存在第 k 个元素
q->link = p->link; // 被删除的 q 的下一个元素与 p 一样
}
/* 从链表中删除该元素
保存第 k 个元素并释放节点 p
注意:此处不保存 p 的值域,释放 p 也无问题 */
x = p->data;
delete p;
return *this;
}
template<class T>Chain<T>& Chain<T>::Insert(int k, const T& x)
{
// 在第 k 个元素之后插入 x
// 如果无第 k 个元素,则引发异常 OutOfBounds
// 如果没有足够的空间,则传递 NoMem 异常
if (k < 0)
throw OutOfBounds();
// p 最终将指向第 k 个节点
ChainNode<T> *p = first;
// 将 p 移动至第 k 个元素
for (int index = 1; index < k && p; index++)
p = p->link;
// 如果 k = 0,表明往空链表中插入首个元素,此时 p 为 NULL
// 如果 k > 0,如有 k 个元素,则 p 不再为 NULL
if (k > 0 && !p)
throw OutOfBounds();
// 插入
ChainNode<T> *y = new ChainNode<T>;
y->data = x;
if (k)
{
// 在 p 之后插入
y->link = p->link;
p->link = y;
}
else
{
// 作为第一个元素插入,注意 first 为 0
y->link = first;
first = y;
}
return *this;
}
二、chain+.h 改进版链表类
/*///
链表类 Chain 改进版(速度优化)
说明:
new、delete 耗费大量时间,新版本将
释放的节点放入自由节点链表,只有在
自由节点链表为空时才用 new 分配空间
New:当自由节点链表用完时才调用new
Delete:将被删除的节点放入自由节点表
///*/
#pragma once
#include<iostream>
#include"xcept.h"
using namespace std;
template<class T> class Chain2;
template <class T>class ChainNode2
{
friend Chain2<T>;
private:
T data;
ChainNode2<T> *link, *freelst;
};
template<class T>class Chain2
{
public:
Chain2()
{
first = 0, freelst = 0;
}
~Chain2();
bool IsEmpty() const
{
return (first == 0);
}
int Length() const;
bool Find(int k, T& x) const;
int Search(const T& x) const;
Chain2<T>& Delete(int k, T& x);
Chain2<T>& Insert(int k, const T& x);
void Output(ostream& out) const;
ChainNode2<T>* New();
private:
ChainNode2<T> *first, *freelst; // 指向第一个节点的指针
void FreeNode(ChainNode2<T>* node);
};
template<class T>Chain2<T>::~Chain2()
{
// 链表的析构函数,用于删除链表中的所有节点
ChainNode2<T> *next; // 下一个节点
while (first)
{
next = first->link;
delete first;
first = next;
}
}
template<class T>int Chain2<T>::Length() const
{
// 返回链表中的元素总数
ChainNode2<T> *current = first;
int len = 0;
while (current)
{
len++;
current = current->link;
}
return len;
}
template<class T>bool Chain2<T>::Find(int k, T& x) const
{
/* 寻找链表中的第 k 个元素,并将其传送至 x
如果不存在第 k 个元素,则返回 false,否则返回 true */
if (k<1)
return false;
ChainNode2<T> *current = first;
int index = 1; // current的索引
while (index < k && current)
{
current = current->link;
index++;
}
if (current) // 如为 NULL,则链表没有 k 个元素(提前结束)
{
x = current->data;
return true;
}
return false; // 不存在第 k 个元素
}
template<class T>int Chain2<T>::Search(const T& x) const
{
/* 寻找 x,如果发现 x,则返回 x 的地址
如果 x 不在链表中,则返回 0 */
ChainNode2<T> *current = first;
int index = 1; // current的索引
// 假定对于类型 T 定义了 != 操作
while (current && current->data != x)
{
current = current->link;
index++;
}
if (current)
return index;
return 0;
}
template<class T>void Chain2<T>::Output(ostream& out) const
{
// 将链表元素送至输出流
ChainNode2<T> *current;
for (current = first; current; current = current->link)
out << current->data << " ";
}
// 重载<<(对类型 T 定义 << 操作)
template <class T>ostream& operator<<(ostream& out, const Chain2<T>& x)
{
x.Output(out);
return out;
}
template<typename T>void Chain2<T>::FreeNode(ChainNode2<T>* node)
{
if (freelst)
freelst->link = node;
else
freelst = node;
}
template<class T>Chain2<T>& Chain2<T>::Delete(int k, T& x)
{
// 把第 k 个元素取至 x,然后从链表中删除第 k 个元素
// 如果不存在第 k 个元素,则引发异常 OutOfBounds
if (k < 1 || !first)
throw OutOfBounds(); // 不存在第 k 个元素
// p 最终将指向第 k 个节点
ChainNode2<T> *p = first;
// 将 p 移动至第 k 个元素,并从链表中删除该元素
if (k == 1) // p 已经指向第 k 个元素
{
first = first->link; // 删除之
}
else
{
// 用 q 指向第 k-1 个元素
ChainNode2<T> *q = first;
for (int index = 1; index < k - 1 && q; index++)
q = q->link;
if (!q || !q->link) // 无第 k 个元素(q 只到 k-1 个)
throw OutOfBounds();
p = q->link; // 存在第 k 个元素
q->link = p->link; // 被删除的 q 的下一个元素与 p 一样
}
/* 从链表中删除该元素
保存第 k 个元素并释放节点 p
注意:此处不保存 p 的值域,释放 p 也无问题 */
x = p->data;
FreeNode(p);
return *this;
}
template<typename T>ChainNode2<T>* Chain2<T>::New()
{
ChainNode2<T> *current;
if (freelst)
{
current = freelst;
freelst = freelst->link;
return current;
}
return new ChainNode2 < T > ;
}
template<class T> Chain2<T>& Chain2<T>::Insert(int k, const T& x)
{
// 在第 k 个元素之后插入 x
// 如果无第 k 个元素,则引发异常 OutOfBounds
// 如果没有足够的空间,则传递 NoMem 异常
if (k < 0)
throw OutOfBounds();
// p 最终将指向第 k 个节点
ChainNode2<T> *p = first;
// 将 p 移动至第 k 个元素
for (int index = 1; index < k && p; index++)
p = p->link;
// 如果 k = 0,表明往空链表中插入首个元素,此时 p 为 NULL
// 如果 k > 0,如有 k 个元素,则 p 不再为 NULL
if (k > 0 && !p)
throw OutOfBounds();
// 插入
ChainNode2<T> *y = New();
y->data = x;
if (k)
{
// 在 p 之后插入
y->link = p->link;
p->link = y;
}
else
{
// 作为第一个元素插入,注意 first 为 0
y->link = first;
first = y;
}
return *this;
}
</pre><pre name="code" class="cpp">xcept.h 是异常处理头文件(略)。测试代码:
</pre><pre name="code" class="cpp">
#include <iostream>
#include "schain.h"
#include "schain+.h"
#include <ctime>
using namespace std;
int main(void)
{
int n;
clock_t start, finish;
double a, b;
Chain<int>c;
start = clock();
for (int i = 0; i != 10000000; ++i)
{
c.Insert(0, i + 1);
c.Delete(1, n);
}
finish = clock();
cout << "用时:" << (a=(finish - start)/1000.0) <<"秒"<< endl;
Chain2<int>c2;
start = clock();
for (int i = 0; i != 10000000; ++i)
{
c2.Insert(0, i + 1);
c2.Delete(1, n);
}
finish = clock();
cout << "用时:" << (b=(finish - start) / 1000.0) << "秒" << endl;
cout << "速度提升约"<< a / b <<"倍"<< endl;
system("pause");
return 0;
}
运行结果: