速度优化的链表类

一、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;
}


 运行结果: 
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值