作为半路出家的码农,前段时间去试了下程序猿行业水的深浅,参加了几家互联网公司实习生的笔面试,然后就有问到这个问题:单链表反转。
总结了下实现的方法,根据是否改变原链表结构,主要分出两个方法:一是原地反转,二是新建链表实现原链表的反转链表。
前者主要是实现思路是从第二个节点开始不断把每个节点换插到头指针指向的地方,直到尾节点。下面是我的具体实现代码:
node*reverselocal(node*head) //传入原链表头指针,返回反转后链表头指针
{node*temp,*p;
if(!head)
{ cerr<<"Hey guy! Empty pointer!"<<endl;
return NULL;
}
temp=head;
while(temp->next!=NULL) //temp一直存着原链表第一个节点的地址,虽然它在链表中的先后位置在变化
{p=temp->next;
temp->next=p->next;
p->next=head;
head=p;
}
return head;
}
后者,是顺序遍历原链表,把原链表每个节点作一份拷贝,然后将每个拷贝依次头插到新链表中去。下面是我的具体实现代码:
node* reversenew(node*head) //传入原链表头指针,返回反转后链表头指针
{ node*temp=head;
node*temp1=NULL,*head1=NULL;
while(temp)
{ temp1=(node*)malloc(sizeof(node));
temp1->num=temp->num;
temp1->next=head1;
head1=temp1;
temp=temp->next;
}
return head1;
}
下面些了一份测试代码用以检测正确性:
#include<iostream>
#include<malloc.h>
using namespace std;
typedef struct node{
int num;
node* next;
}node;
node*reverselocal(node*head)
{node*temp,*p;
if(!head)
{ cerr<<"Hey guy! Empty pointer!"<<endl;
return NULL;
}
temp=head;
while(temp->next!=NULL)
{p=temp->next;
temp->next=p->next;
p->next=head;
head=p;
}
return head;
}
node* reversenew(node*head)
{ node*temp=head;
node*temp1=NULL,*head1=NULL;
while(temp)
{ temp1=(node*)malloc(sizeof(node));
temp1->num=temp->num;
temp1->next=head1;
head1=temp1;
temp=temp->next;
}
return head1;
}
int main()
{ node*head,*t;
t=head=(node*)malloc(sizeof(node));
head->num=0;
head->next=NULL;
for(int i=1;i<20;i++)
{ t->next=(node*)malloc(sizeof(node));
t->next->num=i;
t->next->next=NULL;
t=t->next;
} //初始化链表完毕
t=reverselocal(head); //两个方法分别调用reverselocal(head)和 reversenew(head)函数来进行
//t= reversenew(head);
while(t) //输出反转结果
{cout<<t->num<<" ";
t=t->next;
}
cout<<endl;
return 1;
}