正文

详解链表的转置问题。2007-02-15 01:40:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/andyhou/23367.html

分享到:

//题目:                      ------------------链表的转置------------------------// 要求://      将链表的就地转置。就是将链表的数据存储倒置//例://     输入:12345678910//     输出:10987654321 // 算法分析://         程序最主要的地方再于将头接点的后的每个接点都放再头接点的前面。直到头接点到达//         尾接点。记完成了链表的转置。// 算法复杂度分析://         只是将每个接点前移所以复杂度就链表的长度。O(N);// 程序分析://          程序采用的时C++实现的方式;时用类实现每个接点。程序中用到了可利用空间表,从而加快了//          程序中要删除接点再生成接点的速度。采用C++的重载new和delete函数。也用到了静态的类成员//          数据成员用来实现可利用空间表。 #include  <iostream>using namespace std;//数据接点的类的实现。template <class Elem>class List{ private:  static List<Elem>* freelist;//静态类成员 public:  Elem data;  List* next;  List(Elem dataval,List* nextval=NULL)//构造函数同时进行类的初始化。  {   data=dataval;   next=nextval;  }  List(List* nextval=NULL)  {   next=nextval;  }  void* operator new(size_t);//new重载函数的声明。  void operator delete(void*);//delete重载函数的声明。  ~List(){};}; template<class Elem>List<Elem>* List<Elem>::freelist=NULL;// 静态类数据成员的初始化。 // new 重载函数的实现。记得因为是模板函数。所以要记得返回的时候时不指向任何类型的。// 当你再用到new函数时它就能重新指向你需要的类型。template <class Elem>void* List<Elem>::operator new(size_t){ if(freelist==NULL)    //生成一个接点单位的可利用空间表。同样也可以生成多个  return ::new List;  //如:::new List[n],n是你想生成接点的个数。 List<Elem>* temp=freelist; freelist=freelist->next; return temp;} template<class Elem>//    delete重载函数的实现。void List<Elem>::operator delete(void *ptr){ ((List<Elem>*)ptr)->next=freelist;  //因为void* ptr是不指向任何类型的指针。所以要记得强制 freelist=(List<Elem>*)ptr;           // 转换为List<Elem>*型的指针。}//template<class Elem>class AList{ private:  List<Elem>* head;  //头指针。  List<Elem>* tail;  //尾指针。  List<Elem>* fence; //标记指针。  int size;          //链表长度。 public:  AList()  {   head=tail=fence=new List<Elem>; //初始化   size=0;  }  ~AList()  {      while(head!=NULL)   {    fence=head;    fence=fence->next;    delete fence;   }  }  bool append(const Elem&);  void print() const;  bool changList();};//为了能更好的看到转置的效果我时从尾接点插入数据的。template<class Elem>bool AList<Elem>::append(const Elem& T){ if(size==0)          //不设置空的头接点。 {  head->data=T;  tail=head;  tail->next=NULL;  ++size;  return true; } tail=tail->next=new List<Elem>(T,NULL); size++; return true;}//打印所有数据的函数。这个是不带头接点的打印函数。带头接点的将不同。要从head->next开始。//而不是从head开始。template <class Elem>void AList<Elem>::print() const{ List<Elem>* temp=head;    cout<<"<";  while(temp!=fence)  {   cout<<temp->data<<" ";   temp=temp->next;  }  cout<<"|";  while(temp!=NULL)  {   cout<<temp->data<<" ";   temp=temp->next;  }  cout<<">";}//这个就是程序转置函数。要转置记得你要三个接点才能实现。template<class Elem>bool AList<Elem>::changList(){ List<Elem>* temp=head;//temp接点是为了当后面的接点再头接点插入时保证它始终是头接点。 if(head->next==NULL)//链表为空退出。  return false; while(head->next!=NULL)//当开始的头接点到达尾接点时结束。 {  fence=head->next;      //首先将标记接点设置再开始头接点的下一个接点。以保证它始终往后移。  head->next=fence->next;//删除开始头接点的下一个接点。  fence->next=temp;    //将删除的接点放到了最前面的接点。    temp=fence;    //再将放置头接点的接点做为现在的头接点。 } tail=head;  //开始的头接点变成现在的尾接点了。所以赋给尾接点。 head=temp;  //再将现在的头接点赋给原来的头接点。实现了所有的有标记的接点回位。 return true;} int main(){ AList<char> A; char item[100]; cout<<"  Enter the --10 --char you want to:"; cin>>item; for(int i=0;i<10;i++) {  A.append(item[i]);     //输入数据。 } cout<<"print all element before changing:"<<endl; A.print();             //转置前的数据位置。 A.changList();         //转置 cout<<"print all element after changed:"<<endl; A.print();             //转置后的数据位置。 return 0;}//程序运行结果样例://   Enter the ---10---char you want to:houyonghua//   print all element before changing     //   <|h o u y o n g h u a >//   print all element after changed//   <|a u h g n o y u o h >//同样程序修改AList<Elem>中的类型也可以进行其他类型的输入和输出。//            -----------------------------程序实验结束--------------------- 注:        也许有许多人做过同样的题目,但是也有些同学还是不能解决此题。我这里有很详细的讲解。不过我也是初学者,有不对的地方请高手指点。

阅读(3942) | 评论(2)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册