//基于链表的类Chain
#include <iostream>
#include<new.h>
using namespace std;
//节点类,定义了每个节点的存储类型和指针名称
template<class T>
class ChainNode{
public:
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; //返回第k个元素到x中
int Search(const T&x)const; //返回x所在的位置
Chain<T>& Delete(int k,T& x); //删除第k个元素并把它返回到x中
Chain<T>& Insert(int k,const T&x); //在第k个元素之后插入x
void Output(ostream& out) const; //重载操作符的输出函数
ChainNode<T> *first; //指向第一个节点的指针
ChainNode<T> *last; //指向最后一个节点的指针
void Erase();
void Zero(){first=0;};
Chain<T>& Append(const T&x);
};
//链表遍历器类实现对链表的遍历
template<class T>
class ChainIterator{
public:
T* Initialize(const Chain<T>&c){
location = c.first;
if(location){
return &location->data;//为何有地址符?
}
return 0;
}
T* Next(){
if(!location)
return 0;
location = location->link;
if(location)
return &location->data;
return 0;
}
private:
ChainNode<T>*location;
};
//链表的析构函数,用于删除所有的链表中的节点
template<class T>
Chain<T>::~Chain(){
Erase();
}
//清除掉链表中的所有元素并且释放内存
template<class T>
void Chain<T>::Erase(){
ChainNode<T>*next;
//指向下一个节点
while(first){
next=first->link;
delete first;
first = next;
}
}
//输出链表
template<class T>
void Chain<T>::Output(ostream& out)const{
ChainNode<T>*current;
for(current=first;current;current=current->link){
out<<current->data;
if(!current->link){
out<<""<<endl;
}else{
out<<",";
}
}
}
//重载操作符
template<class T>
ostream& operator<<(ostream& out,const Chain<T>&x){
x.Output(out);
return out;
}
class OutOfBounds{
public:
OutOfBounds(){
cout<<"Out Of Bounds!"<<endl;
}
};
//内存不足的异常类
class NoMem{
public:
NoMem(){
cout<<"No Memory!"<<endl;
}
};
//使new引发NoMem异常而不是xalloc异常
//如果要恢复原始行为可以做以下调用
//_set_new_handler(Old_Handler);
int my_new_handler(size_t size){
throw NoMem();
}
//确认链表的长度
template<class T>
int Chain<T>::Length()const{
ChainNode<T>*current = first;
int length = 0;
while(current){
length++;
current = current->link;
}
return length;
}
//在链表中查找第k个元素
//存在就储存到x中
//不存在则返回false,否则返回true
template<class T>
bool Chain<T>::Find(int k,T&x)const{
if(k<1)
return false;
ChainNode<T>*current = first;
int index = 1;
while(index<k&¤t){
current = current->link;
index++;
}
if(current){
x = current->data;
return true;
}
return false;
}
//在链表中搜索
//查找x,如果发现则返回x的下标
//如果x不存在则返回0
template<class T>
int Chain<T>::Search(const T&x)const{
ChainNode<T>*current = first;
int index = 1;
while(current&¤t->data!=x){
current = current->link;
index++;
}
if(current){
return index;
}
return 0;
}
//从链表中删除一个元素
//将第k个元素取至x
//然后从链表中删除第k个元素
//如果不存在则引发异常OutOfBounds
template<class T>
Chain<T>& Chain<T>::Delete(int k,T& x){
if(k<1||!first){
throw OutOfBounds();
}
ChainNode<T>*p = first;
if(k==1){
first = first->link;
}else{
ChainNode<T>*q = first;
for(int index = 1;index<k-1&&q;index++){
q = q->link;
//此时q指向要删除的前一个节点
}
if(!q||!q->link){
throw OutOfBounds();
}
p = q->link;
if(p==last)
last=q;
q->link=p->link;
//从链表中删除该节点
x = p->data;
delete p;
return *this;
}
}
//在第k个位置之后插入元素
//不存在则报OutOfBounds异常
//没有足够内存则报NoMem异常
template<class T>
Chain<T>& Chain<T>::Insert(int k,const T&x){
if(k<0){
throw OutOfBounds();
}
ChainNode<T>*p = first;
for(int index = 1;index<k && p;index++){
p = p->link;
}
if(k>0 && !p){
throw OutOfBounds();
}
ChainNode<T>*y = new ChainNode<T>;
y->data = x;
if(k){
y->link=p->link;
p->link=y;
}else{
//作为第一个元素插入
y->link = first;
first = y;
}
if(!y->link)
last=y;
return *this;
}
//在链表右端添加一个数据
template<class T>
Chain<T>& Chain<T>::Append(const T&x){
ChainNode<T>*y;
y = new ChainNode<T>;
y->data = x;
y->link = 0;
if(first){
last->link = y;
last = y;
}else{
first = last = y;
}
return *this;
}
int main(){
//设置当使用new创建对象存在空间不足的问题时调用自己的解决方法
_set_new_handler(my_new_handler);
try{
Chain<int>myList;
cout<<"myList : "<<myList<<endl;
cout<<"Length = "<<myList.Length()<<endl;
cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;
myList.Append(5);
myList.Append(0);
myList.Insert(1,2);
cout<<"myList : "<<myList<<endl;
cout<<"Length = "<<myList.Length()<<endl;
cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;
int f ;
myList.Find(1,f);//把第一个位置的元素赋值给z了
cout<<"First is "<<f<<endl;
cout<<"Length = "<<myList.Length()<<endl;
myList.Delete(1,f);
cout<<"Delete is "<<f<<endl;
cout<<"myList : "<<myList<<endl;
cout<<"Length = "<<myList.Length()<<endl;
cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;
cout<<"Iterator : "<<endl;
//使用遍历器输出
int *x;
ChainIterator<int>c;
x=c.Initialize(myList);
while(x){
cout<<*x;
x = c.Next();
if(x){
cout<<",";
}else{
cout<<""<<endl;
}
}
cout<<endl;
}catch(exception e){
cout<<"Hey!An exception has occurred!";
}
return 0;
}
[C++]数据结构:基于链表结构的Chain类和遍历器ChainIterator类
最新推荐文章于 2024-07-10 22:41:59 发布