数据结构与算法 p45-002
设定一个单向链表,试设计一个既节约时间又节约空间的算法来找出该链表的倒数第m个元素。
实现这个算法,并对可能出现的特殊情况作出相应处理。
(倒数第m个元素 的含义:但m=0时,链表的最后一个元素被返回)
a)顺序表
#include<iostream.h>
typedef int T;
template<class T>
struct Node
{
T data;
Node *next;
};
template <class T>
class LinkList
{
private:
Node<T> *Head;
public:
LinkList() ;
~LinkList();
void CreateList(int n);
void Insert(int i,T e);
T GetElem(int i);
void ListDisplay();
};
template<class T>
LinkList<T>::LinkList()
{
Head=new Node<T>;
Head->next=NULL;
}
template<class T>
LinkList<T>::~LinkList()
{
Node<T> *p;
while(Head)
{
p=Head;
Head=Head->next;
delete p;
}
Head=NULL;
}
template<class T>
void LinkList<T>::CreateList(int n)
{
Node<T> *p,*s;
p=Head;
cout<<"请依次输入"<<n<<"个元素值:"<<endl;
for(int i=1;i<=n;i++)
{
s=new Node<T>;
cin>>s->data;
s->next=p->next;
p->next=s;
p=s;
}
}
template<class T>
T LinkList<T>::GetElem(int i)
{
Node<T> *p;
p=Head->next;
int j=1;
while(p&&j<i)
{
p=p->next;j++;
}
if(!p||j>i)
throw "输入位置有错";
else
return p->data;
}
template <class T>
void LinkList<T>::ListDisplay()
{
Node<T> *p;
p=Head->next;
int i=1;
while(p)
{
cout<<p->data<<" ";
p=p->next;
i++;
}
cout<<endl;
}
int main()
{
int i,m;
T e;
LinkList<int> L;
cout<<"请输入要创建的链表中元素个数:";
cin>>i;
cout<<endl;
L.CreateList(i);
cout<<endl;
cout<<"创建的出的链表中元素如下:"<<endl;
L.ListDisplay();
cout<<endl<<"输入该链表的倒数第m个元素的位置:";
cin>>m;
try
{
e=L.GetElem(i-m);
cout<<endl<<"该链表的倒数第"<<m<<"个元素值为:"<<e<<endl;
}
catch(char *err)
{
cout<<err<<endl;
}
return 0;
}
b)单链表
#include<iostream.h>//cout,cin
typedef int T;
template<class T>
struct Node
{
T data;//数据域,存放表元素
Node *next;//指针域,指向下一个结点
};
template <class T>
class LinkList
{
private:
Node<T> *Head;// 链表头指针
public:
LinkList() ;//构造函数, 创建空链表
~LinkList();//析构函数,删除表空间
void CreateList(int n);//创建具有n个元素的线性链表
T GetElem(int i);//获取第i个元素的值
void ListDisplay();//输出表元素
};
template<class T>
LinkList<T>::LinkList()
{//构建函数,建一空链表
Head=new Node<T>;
Head->next=NULL;
}
template<class T>
LinkList<T>::~LinkList()
{//析构函数,释放链表所占空间
Node<T> *p;
while(Head)//从头结点开始,依次释放结点
{
p=Head;
Head=Head->next;
delete p;
}
Head=NULL;//头结点指向空
}
template<class T>
void LinkList<T>::CreateList(int n)
{//尾插法(正序)创建具有n个元素的线性表
Node<T> *p,*s;//设置工作指针。p指向尾结点
p=Head;
cout<<"请依次输入"<<n<<"个元素值:"<<endl;
for(int i=1;i<=n;i++)
{
s=new Node<T>;//新建元素结点
cin>>s->data;//输入新建数据元素值
s->next=p->next;//新结点链入表尾
p->next=s;
p=s;
}
}
template<class T>
T LinkList<T>::GetElem(int i)
{//获取第i个元素的值
Node<T> *p;//设置工作指针
p=Head->next;//从首结点开始
int j=1;//计数器初始化
while(p&&j<i)//定位到第i个元素结点
{
p=p->next;j++;
}
if(!p||j>i)//定位位置不合理:空表或i小于0或i大于表长
throw "输入位置有错";
else //位置合理
return p->data;
}
template <class T>
void LinkList<T>::ListDisplay()
{//遍历显示链表
Node<T> *p;//设置工作指针
p=Head->next;//从首元结点开始遍历
int i=1;//元素位序
while(p)
{
cout<<p->data<<"\t";
p=p->next;
i++;
}
cout<<endl;
}
int main()
{
int i,m;
T e;
LinkList<int> L;
cout<<"请输入要创建的链表中元素个数:";
cin>>i;
cout<<endl;
L.CreateList(i);
cout<<endl;
cout<<"创建的出的链表中元素如下:"<<endl;
L.ListDisplay();
cout<<endl<<"输入该链表的倒数第m个元素的位置:";
cin>>m;
try
{
e=L.GetElem(i-m);
cout<<endl<<"该链表的倒数第"<<m<<"个元素值为:"<<e<<endl;
}
catch(char *err)
{
cout<<err<<endl;
}
return 0;
}