问题描述:
目的:使用C++模板设计单链表的抽象数据类型(ADT)。并在此基础上,使用单链表ADT的基本操作,设计并实现单链表的简单算法设计。
内容:(1)请使用模板设计单链表的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考网盘中的ADT原型文件。)
(2)ADT的简单应用:使用该ADT设计并实现单链表应用场合的一些简单算法设计。
应用6:假设2个线性表分别由单链表A和B存储,其中数据元素按值非递减有序排列(即已经有序),现要求设计一个算法,将A和B归并为一个线性表 , 其数据元素仍按值非递减排列,且表中不存在值相同的元素。要求使用A和B的原存储空间,且B不再单独存在。
参考函数原型:
template
void Merge_L_Pure_Order( LinkList &A, LinkList &B );
输入说明:
第一行:有序单链表A的数据元素(数据元素之间以空格分隔)
第二行:有序单链表B的数据元素(数据元素之间以空格分隔)
输出说明:
如第一行输入值为0、1、2、3之外的值,直接输出“err”
否则:
第一行:单链表A的遍历结果
第二行:单链表B的遍历结果
空行
第四行:归并+提纯后单链表A的遍历结果
SAMPLE INPUT:
0
3 3 5 5 8 8 11 11
2 2 6 8 8 9 11
SAMPLEOUTPUT:
3->3->5->5->8->8->11->11
2->2->6->8->8->9->11
/n2->3->5->6->8->9->11
思路:
题干写的不是特别清楚,实际上,有3行输入,第一行是表明数据类型的0~3,也就是说这道题其实也是要分输入情况的不同进行分类的(题干没有写,但是一定要记得分类,不然会wa3个点:分别是double,char,string)大部分操作和之前的题目是一样的,主要是提纯+归并两步,我这里是分成两步进行的(应该是有同时操作的办法的,大师我比较菜想不出来),因为给的数据是非降序排序这就意味着所有的相同的数都是临近的,所以只要判断前后两个数是否相同。归并我偷了个懒(才不是不会写)A,B两个链表,分别定义一个指针,谁小输出谁,指针后移,如果相同,输出一次,指针同时后移’。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int no,i;
template<class ElemType>
struct LinkNode
{
ElemType data;
LinkNode<ElemType> *next;
LinkNode(LinkNode<ElemType> *ptr = NULL)
{
next = ptr;
}
LinkNode(const ElemType &item, LinkNode<ElemType> *ptr = NULL)
{
next = ptr;
data = item;
}
};
template<class ElemType>
class LinkList
{
private:
LinkNode<ElemType> *head;
public:
LinkList()
{
head = new LinkNode<ElemType>;
}
LinkList(const ElemType &item)
{
head = new LinkNode<ElemType>(item);
}
LinkList(LinkList<ElemType> &List);
~LinkList()
{
ListDestroy();
}
LinkList<ElemType>& operator=(LinkList<ElemType> &List);
void ListDestroy();
void ListClear();
int ListLength() const;
bool ListEmpty() const;
bool InsFirst( ElemType e );
LinkNode<ElemType>* GetHead() const
{
return head;
}
void SetHead(LinkNode<ElemType> *p)
{
*head = *p;
}
ElemType GetElem(int pos);
bool ListInsert(int pos,ElemType e);
bool DelFirst( ElemType &e);
void CreateList_Head(int n, ElemType *A);
void CreateList_Tail(int n, ElemType *A);
ElemType ListDelete(int pos);
bool LocateElem(const ElemType &e, LinkNode<ElemType> *pos);
bool PriorElem(ElemType cur_e, ElemType &pri_e);
bool NextElem(LinkNode<ElemType> *p, ElemType &e);
void ListTraverse() ;
LinkNode<ElemType> *getIndex(int times);
LinkNode<ElemType> *getTail();
void Merge_L_Pure_Order( LinkList<ElemType> &A, LinkList<ElemType> &B );
LinkNode<ElemType> *Pure_up(int *A);
};
template <class ElemType>
LinkList<ElemType>::LinkList(LinkList<ElemType> &List)
{
LinkNode<ElemType> *temp = List.head;
head = new LinkNode<ElemType>(*temp);
LinkNode<ElemType> *temp2 = head;
while(temp)
{
temp2->next = new LinkNode<ElemType>(*temp->next);
temp = temp->next;
temp2 = temp2->next;
}
}
template<class ElemType>
LinkList<ElemType>& LinkList<ElemType>::operator=(LinkList<ElemType> &List)
{
if(!head)
{
this = LinkList(List);
}
else
{
LinkNode<ElemType> *temp1 = List->head;
LinkNode<ElemType> *temp2 = head;
while(temp1 && temp2)
{
*temp1 = *temp2;
temp1 = temp1->next;
temp2 = temp2->next;
}
if(temp1)
{
while(temp1)
{
temp2 = new ElemType(*temp1);
temp1 = temp1->next;
temp2 = temp2->next;
}
return *this;
}
if(temp2)
{
LinkNode<ElemType> temp3 = temp2->next;
while(temp2)
{
temp3 = temp2->next;
delete temp2;
temp2 = temp3;
}
return *this;
}
}
}
template<class ElemType>
void LinkList<ElemType>::ListDestroy()
{
LinkNode<ElemType> *temp = NULL;
while(head)
{
temp = head->next;
delete head;
head = temp;
}
}
template<class ElemType>
void LinkList<ElemType>::ListClear()
{
LinkNode<ElemType> *temp = head->next;
LinkNode<ElemType> *temp2 = NULL;
while(temp)
{
temp2 = temp->next;
delete temp;
temp = temp2;
}
head->next = NULL;
}
template<class ElemType>
int LinkList<ElemType>::ListLength() const
{
int length = 0;
LinkNode<ElemType> *temp = head->next;
while(temp)
{
length ++;
temp = temp->next;
}
return length;
}
template<class ElemType>
bool LinkList<ElemType>::ListEmpty() const
{
if(head->next)
{
return false;
}
else
{
return true;
}
}
template<class ElemType>
bool LinkList<ElemType>::InsFirst(ElemType e)
{
LinkNode<ElemType> *temp = new LinkNode<ElemType>(e);
if(!temp)
{
return false;
}
temp->next = head->next;
head->next = temp;
cout<<endl;
return true;
}
template<class ElemType>
ElemType LinkList<ElemType>::GetElem(int pos)
{
LinkNode<ElemType> *temp = head;
int index = 0;
while(temp && index < pos)
{
temp = temp->next;
index ++;
}
if(!temp || index < pos-1)
{
cout<<"the index of the element you want is wrong"<<endl;
return;
}
return temp->data;
}
template<class ElemType>
bool LinkList<ElemType>::ListInsert(int pos,ElemType e)
{
LinkNode<ElemType> *temp = head;
int index = 0;
while(temp && index < pos - 1)
{
temp = temp->next;
index ++;
}
if(!temp || index < pos-1)
{
cout<<"the index of the element you want is wrong"<<endl;
return false;
}
LinkNode<ElemType> *temp2 = new LinkNode<ElemType>();
temp2->data = e;
temp2->next = temp->next;
temp->next = temp2;
}
template<class ElemType>
bool LinkList<ElemType>::DelFirst(ElemType &e)
{
LinkNode<ElemType> *temp = head->next;
e = temp->data;
if(!temp) return false;
head->next = temp->next;
delete temp;
return true;
}
template<class ElemType>
void LinkList<ElemType>::CreateList_Head(int n,ElemType *A)
{
ElemType *temp = NULL;
for(int i = 0; i < n; i ++)
{
temp = A + i;
InsFirst(*temp);
}
}
template<class ElemType>
void LinkList<ElemType>::CreateList_Tail(int n,ElemType *A)
{
LinkNode<ElemType> *temp=head;
int length = ListLength(),cont = 0;
while(temp && cont < length)
{
temp = temp->next;
cont++;
}
LinkNode<ElemType> *temp2 = temp;
if(!temp || cont<length)
{
return;
}
for(int i = 0; i < n; i ++)
{
temp->next = new LinkNode<ElemType>(*(A+i));
temp = temp->next;
}
}
template<class ElemType>
ElemType LinkList<ElemType>::ListDelete(int pos)
{
LinkNode<ElemType> *temp = head;
int i = 0;
while(temp && i < pos - 1)
{
temp = temp->next;
i ++;
}
if(!temp || i < pos - 1)
{
cout<<"the position you input is invalid"<<endl;
return ElemType();
}
LinkNode<ElemType> *temp2 = NULL;
temp2 = temp->next;
temp->next = temp2->next;
ElemType result = temp2->data;
delete temp2;
return result;
}
template<class ElemType>
bool LinkList<ElemType>::LocateElem(const ElemType &e, LinkNode<ElemType> *pos)
{
LinkNode<ElemType> *temp = head;
while(temp)
{
if(temp->data == e)
{
pos->data = temp->data;
pos->next = temp->next;
return true;
}
temp = temp->next;
}
return false;
}
template<class ElemType>
bool LinkList<ElemType>::PriorElem(ElemType cur_e, ElemType &pri_e)
{
LinkNode<ElemType> *temp = head;
while(temp->next)
{
if(temp->next->data == cur_e)
{
pri_e = temp->data;
return true;
}
temp = temp->next;
}
return false;
}
template<class ElemType>
bool LinkList<ElemType>::NextElem(LinkNode<ElemType> *p, ElemType &e)
{
if(LocateElem(e,p))
{
p = p->next;
return true;
}
else
{
return false;
}
}
template<class ElemType>
LinkNode<ElemType>*Pure_up(ElemType *A)
{
LinkNode<ElemType> *Afront = A.GetHead()->next;
LinkNode<ElemType> *Aback = A.GetHead()->next;
while(Aback)
{
if(Aback->data != Afront->data)
{
Afront->next = Aback;
Afront = Aback;
}
Aback = Aback->next;
}
Afront->next = NULL;
}
template<class ElemType>
void LinkList<ElemType>::ListTraverse()
{
LinkNode<ElemType>*temp=head->next;
while(temp)
{
cout<<temp->data;
temp=temp->next;
if(temp)
cout<<"->";
}
cout<<endl;
}
template<class ElemType>
LinkNode<ElemType> *LinkList<ElemType>::getTail()
{
LinkNode<ElemType> *temp = head;
while(temp->next)
{
temp = temp->next;
}
return temp;
}
template<class ElemType>
LinkNode<ElemType> *LinkList<ElemType>::getIndex(int times)
{
LinkNode<ElemType> *temp=head;
while(times--)
{
temp=temp->next;
}
return temp;
}
template<class ElemType>
void Merge_L_Pure_Order( LinkList<ElemType> &A, LinkList<ElemType> &B )
{
LinkNode<ElemType> *Afront = A.GetHead()->next;
LinkNode<ElemType> *Aback = A.GetHead()->next;
while(Aback)
{
if(Aback->data != Afront->data)
{
Afront->next = Aback;
Afront = Aback;
}
Aback = Aback->next;
}
Afront->next = NULL;
LinkNode<ElemType> *Bfront = B.GetHead()->next;
LinkNode<ElemType> *Bback = B.GetHead()->next;
while(Bback)
{
if(Bback->data != Bfront->data)
{
Bfront->next = Bback;
Bfront = Bback;
}
Bback = Bback->next;
}
Bfront->next = NULL;
LinkNode<ElemType> *Atemp=A.GetHead()->next;
LinkNode<ElemType> *Btemp=B.GetHead()->next;
if(Atemp->data<Btemp->data)
{
cout<<Atemp->data;
Atemp=Atemp->next;
}
else if(Atemp->data>Btemp->data)
{
cout<<Btemp->data;
Btemp=Btemp->next;
}
else
{
cout<<Atemp->data;
Atemp=Atemp->next;
Btemp=Btemp->next;
}
while(Atemp&&Btemp)
{
if(Atemp->data<Btemp->data)
{
cout<<"->"<<Atemp->data;
Atemp=Atemp->next;
}
else if(Atemp->data>Btemp->data)
{
cout<<"->"<<Btemp->data;
Btemp=Btemp->next;
}
else
{
cout<<"->"<<Atemp->data;
Atemp=Atemp->next;
Btemp=Btemp->next;
}
}
if(Atemp)
{
while(Atemp)
{
cout<<"->"<<Atemp->data;
Atemp=Atemp->next;
}
}
if(Btemp)
{
while(Btemp)
{
cout<<"->"<<Btemp->data;
Btemp=Btemp->next;
}
}
}
int main()
{
LinkList<int> A;
LinkList<int> B;
int n;
cin>>n;
getchar();
if(n!=0&&n!=1&&n!=2&&n!=3)
{
cout<<"err";
exit(0);
}
string s1,s2;
getline(cin,s1);
getline(cin,s2);
if(n==0)
{
int temp1[10005],temp2[10005];
int cont1=0,cont2=0;
int num1=0,num2=0;
for (unsigned i=0; i<s1.size(); i++)
{
if (s1[i]==' ')
{
temp1[cont1++]=num1;
num1=0;
}
else
{
num1=num1*10+s1[i]-'0';
}
}
temp1[cont1++]=num1;
for (unsigned i=0; i<s2.size(); i++)
{
if (s2[i]==' ')
{
temp2[cont2++]=num2;
num2=0;
}
else
{
num2=num2*10+s2[i]-'0';
}
}
temp2[cont2++]=num2;
A.CreateList_Tail(cont1,temp1);
A.ListTraverse();
B.CreateList_Tail(cont2,temp2);
B.ListTraverse();
cout<<endl;
Merge_L_Pure_Order(A,B);
}
if(n==1)
{
double temp1[10005],temp2[10005];
double num1=0.0,sum1=0.0,num2=0.0,sum2=0.0;
int judge1=0,t1=0,judge2=0,t2=0;
int j1=0,j2=0;
for(unsigned i=0; i<s1.size(); i++)
{
if(s1[i]==' ')
{
num1=num1/pow(10,t1);
temp1[j1++]=num1;
num1=0.0;
judge1=0,t1=0;
}
else if(s1[i]=='.')
{
judge1=1;
}
else
{
num1=num1*10+s1[i]-'0';
if(judge1==1)
{
t1++;
}
}
}
num1=num1/pow(10,t1);
temp1[j1++]=num1;
LinkList<double> A;
A.CreateList_Tail(j1,temp1);
A.ListTraverse();
for(unsigned i=0; i<s2.size(); i++)
{
if(s2[i]==' ')
{
num2=num2/pow(10,t2);
temp2[j2++]=num2;
num2=0.0;
judge2=0,t2=0;
}
else if(s2[i]=='.')
{
judge2=1;
}
else
{
num2=num2*10+s2[i]-'0';
if(judge2==1)
{
t2++;
}
}
}
num2=num2/pow(10,t2);
temp2[j2++]=num2;
LinkList <double> B;
B.CreateList_Tail(j2,temp2);
B.ListTraverse();
cout<<endl;
Merge_L_Pure_Order(A,B);
}
if(n==2)
{
char c1[10005],c2[10005];
char ch1,ch2;
int j1=0,j2=0;
for(unsigned i=0; i<s1.size(); i++)
{
ch1=s1[i];
if(ch1!=' ')
{
c1[j1++]=ch1;
}
}
LinkList<char> A;
A.CreateList_Tail(j1,c1);
A.ListTraverse();
for(unsigned i=0; i<s2.size(); i++)
{
ch2=s2[i];
if(ch2!=' ')
{
c2[j2++]=ch2;
}
}
LinkList<char> B;
B.CreateList_Tail(j2,c2);
B.ListTraverse();
cout<<endl;
Merge_L_Pure_Order(A,B);
}
if(n==3)
{
string d1[10005],d2[10005];
string k1,k2;
k1.clear();
k2.clear();
int j1=0,j2=0;
for(unsigned i=0;i<s1.size();i++)
{
if(s1[i]==' ')
{
d1[j1]=k1;
j1++;
k1.clear();
}
else
{
k1+=s1[i];
}
}
d1[j1++]=k1;
LinkList<string> A;
A.CreateList_Tail(j1,d1);
A.ListTraverse();
for(unsigned i=0;i<s2.size();i++)
{
if(s2[i]==' ')
{
d2[j2]=k2;
j2++;
k2.clear();
}
else
{
k2+=s2[i];
}
}
d2[j2++]=k2;
LinkList<string> B;
B.CreateList_Tail(j2,d2);
B.ListTraverse();
cout<<endl;
Merge_L_Pure_Order(A,B);
}
return 0;
}