记录一下,我发现自己自从开始学数据结构,一个很大很大的问题就是,例如一个表中的结点*s,s和s->next交叉出现,以及什么时候对s->next判空,什么时候对s判空,都是需要结合你自己的算法步骤来选择的,而不去模拟清楚这个过程,就会出现很大的问题,尤其是做一些比较复杂,然后需要对多个条件进行判断的题目,更是容易自己把自己弄混。自查很难,所以每一步都要想清楚
最好手边都要放一本草稿本,模拟一下过程,瞬间清晰有没有
#include <iostream>
using namespace std;
template <typename T>
struct LinkList
{
T data;
LinkList<T> *next;//指向下一个结点的域
};
template <typename T>
class LinkListClass
{
LinkList<T> *head;//必须是指针,否则不能动态开辟内存空间
int length;
public:
LinkListClass();//构造函数
void CreateL();//尾插法
void DispList();//显示链表元素
// bool sort(LinkListClass<T> & T1);
void sort (LinkListClass<T> &a,LinkListClass<T> &b,LinkListClass<T> &c);
};
template <typename T>
LinkListClass<T>::LinkListClass()
{
head=new LinkList<T>();
head->next=NULL;
head->data=0;
length=0;
}
template <typename T>
void LinkListClass<T>::CreateL()
{
length=0;
LinkList<T> *s,*p;
T a;
s=head;//是s=head,而不是s=&head
while(cin>>a&&a!=-1)
{
p=new LinkList<T>();
s->next=p;
p->next=NULL;
p->data=a;
s=p;
length++;
}
}
template <typename T>
void LinkListClass <T>::DispList()
{
LinkList<T> *tmp;
tmp=head->next;
for(int i=0;tmp!=NULL;i++)
{
cout<<tmp->data<<" ";
tmp=tmp->next;
}
}
/*template <typename T>
bool LinkListClass<T>::sort(LinkListClass<T> & T1)
{
LinkList<T> *p;
LinkList<T> *t;
LinkList<T> *s;
p=head;
t=T1.head;
while(t->next!=NULL)//t!=NULL判空时出现问题
{
t=t->next;
while(p!=NULL)
{
p=p->next;
cout<<"p:"<<p->data<<endl;
//cout<<"t:"<<t->data<<endl;
if((t->data)>=(p->data))
{
s=new LinkList<T>();
s->next=p->next;//p->next->next
s->data=t->data;
p->next=s;
cout<<"s:"<<s->data<<endl;
cout<<"s->next->data:"<<s->next->data<<endl;
break;
//continue;
}*/
/* while(p->next!=NULL)//判空时出现问题
{
p=p->next;
cout<<"p:"<<p->data<<endl;
while(t->next!=NULL)
{
t=t->next;
//cout<<"t:"<<t->data<<endl;
if((t->data)>=(p->data))
{
s=new LinkList<T>();
s->next=p->next;//p->next->next
s->data=t->data;
p->next=s;
break;
//continue;
}
if(t->next==NULL)
{
p->next=T1.head;
return true;
}
}
}
return true;
}*/
template <typename T>
void LinkListClass<T>::sort(LinkListClass<T> &a,LinkListClass<T> &b,LinkListClass<T> &c)
{
LinkList<T> *toa;
LinkList<T> *tob;
LinkList<T> *toc;
LinkList<T> *s;
toa=head->next;
tob=b.head->next;
toc=c.head;
while((toa!=NULL)||(tob!=NULL))
//((toa!=NULL)&&(tob!=NULL))肯定不是用与,我这个傻子,与一下子就把能进行循环的条件缩小了
//(toa->next!=NULL&&tob->next!=NULL)
//也肯定不会用next来进行判空!因为toa/tob本身可能会走到最后一个元素的后面,自己成为空,在每个实现循环里已经走过了这个next的步骤,所以不会再用next来判空,否则重复
{
//之前我把创建新节点的步骤每个循环都写一边,直接提出来多方便而且清晰,还是理解不到位,整个过程不够一目了然
s=new LinkList<T>();
toc->next=s;
toc=s;
if((toa!=NULL)&&(tob!=NULL))
//((toa!=NULL)||(tob!=NULL))...toa->next..综上。。。也不是用||来进行if判断
{
if(toa->data<tob->data)
{
s->data=toa->data;
toa=toa->next;
continue;
}
if(toa->data>tob->data)
{
s->data=tob->data;
tob=tob->next;
continue;
}
if(toa->data==tob->data)
{
s->data=toa->data;
toa=toa->next;
tob=tob->next;
continue;
}
}
else
{
if(toa==NULL)
{
s->data=tob->data;
tob=tob->next;
continue;
}
if(tob==NULL)
{
s->data=toa->data;
toa=toa->next;
continue;
}
}
}
}
int main()
{
LinkListClass<int> one,two;
LinkListClass<int> thr;
one.CreateL();
two.CreateL();
one.sort(one,two,thr);
thr.DispList();
}