速度优化的链表类

来源:互联网 发布:java反序列化是什么 编辑:程序博客网 时间:2024/05/17 02:17
一、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 个元素,则引发异常 OutOfBoundsif (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 为 0y->link = first;first = y;}return *this;}


二、chain+.h 改进版链表类
/*///////////////////////////////    链表类 Chain 改进版(速度优化)说明:new、delete 耗费大量时间,新版本将释放的节点放入自由节点链表,只有在自由节点链表为空时才用 new 分配空间New:当自由节点链表用完时才调用newDelete:将被删除的节点放入自由节点表///////////////////////////////*/#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;elsefreelst = node;}template<class T>Chain2<T>& Chain2<T>::Delete(int k, T& x){// 把第 k 个元素取至 x,然后从链表中删除第 k 个元素// 如果不存在第 k 个元素,则引发异常 OutOfBoundsif (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 为 0y->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
原创粉丝点击