您的位置:首页 > 理论基础 > 数据结构算法

[C++]数据结构实验03:链式结构线性表的基本操作

2012-11-21 21:25 561 查看
/**********************************************************************************************************************************/
/*	实验三:线性表操作
/*	1.创建线性表类。线性表的存储结构使用链表。
/*	2.完成表首插入元素、删除指定元素、搜索表中是否有指定元素、输出链表。
/*	3.输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建链表。输出整个链表。
/*	4.输入一个整数,将该数作为一个元素值插入表首位置。输出整个链表。
/*	5.输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
/*	6.再一次输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
/*	7.使用链表遍历器实现链表的反序输出。
/*	8.再一次输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建另外一个链表,输出整个链表。
/*	9.使用链表遍历器实现上面两个链表的合并,输出合并后的链表。
/**********************************************************************************************************************************/

#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&& current){
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&& current->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()
{
int count = 0;

//收集输入的内容至链表a当中
Chain<int> a;

cout<<"Input1"<<endl;
while(true)
{
int b;
cin>>b;
if(b==0)break;
a.Append(b);
count++;
}

cout<<"Output1"<<endl;
cout<<a<<endl;

cout<<"Input2"<<endl;
int c1;
cin>>c1;
a.Insert(0,c1);
count++;
cout<<"Output2"<<endl;
cout<<a<<endl;

cout<<"Input3"<<endl;
int q;
cin>>q;
cout<<"Output3"<<endl;
cout<<a.Search(q)<<endl;

cout<<"Input4"<<endl;
int q2;
cin>>q2;
cout<<"Output4"<<endl;
cout<<a.Search(q2)<<endl;

Chain<int> w;
count = 0;
cout<<"Input5"<<endl;

while(true){
int b;
cin>>b;
if(b==0)break;
w.Append(b);
count++;
}

//直接将w链表遍历加在a链表的尾部
cout<<"Output5"<<endl;
ChainNode<int>*current = w.first;
while (current)
{
a.Append(current->data);
current= current->link;
}
cout<<a<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: