最近看网课,王道的一个老师说,头插可以用来逆转单链表,但是我第一想法就是每次从尾部取,然后头插,时间复杂度是平方,觉得太大了,就想入队列,然后出队建立新表头插,空间复杂度n
所以我想了个比较折中的办法,在n的时间复杂度下,又不会开辟很多空间。
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct list
{
struct list* next;
int data;
}ListNode,* List;
void InitList(List &l)
{
l=(List)malloc(sizeof(ListNode));
l->next=NULL;
}
bool InsertList(List l ,int position,int data)
{
if(position<1)
return false;
int j=0;
ListNode *p=l;
while(p!=NULL&&j<position-1)
{
p=p->next;
j++;
}
if(p==NULL)
return false;
ListNode *s=(ListNode *)malloc(sizeof(ListNode));
s->data=data;
s->next=p->next;
p->next=s;
}
void ShowList(List l)
{
ListNode *p=l->next;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
}
void ReserveList(List l)
{
if(l->next==NULL||l->next->next==NULL)//单个节点和空链表直接劝退
return;
ListNode *p=l->next->next;//从第二个节点开始
l->next->next=NULL;//别忘了最特殊的,现在的第一个,逆转后的尾节点,要实现改下next指针与
ListNode * q;//用来记录
while(p!=NULL)//如果p不是空
{
q=p->next;//记录下这个链表的下一个序列,因为要头插,所以会丢失后面的序列
p->next=l->next;//头插
l->next=p;
p=q;//链表原来序列的下一个继续这个过程
}
}
int main()
{
List l;
InitList(l);
int data;
while(cin>>data)
{
if(!InsertList(l,1,data))
break;
}
ReserveList(l);
ShowList(l);
}