题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
思路:
假设有链表A->B->C->D->E->F->G。在反转链表过程中的某一阶段,其链表指针指向为:A<-B<-C<-D E->F->G。也就是说在结点D之前的所有结点都已经反转,而结点D后面的结点E开始的所有结点都没有反转。这样D跟E之间存在了断裂,所以不仅需要保存当前结点和它的前一个结点,还需要保存当前结点的下一个结点,一共需要3个指针来操作
第一个指针pre用来保存当前结点的前一个结点
第二个指针now用来指向当前结点
第三个指针用来保存当前结点的下一个指针,因为反转当前结点的指针时:now->next=pre,会丢失now->next
代码如下:
struct listnode { int data; listnode *next; }; //下面所用的链表头结点都是空的 //尾插法创建链表 listnode *init() { listnode *head=(listnode *)malloc(sizeof(listnode)); head->next=NULL; listnode *p=head; cout<<"please input a number(按-1结束)"<<endl; int data; cin>>data; while(data!=-1) { listnode *temp=(listnode *)malloc(sizeof(listnode)); temp->data=data; temp->next=p->next; p->next=temp; p=temp; cout<<"please input a number(按-1结束)"<<endl; cin>>data; } return head; } //打印链表 void print(listnode *head) { listnode *p=head->next; while(p) { cout<<p->data<<" "; p=p->next; } cout<<endl; } //反转链表(使用三个指针分别指向当前结点,当前结点的前一个结点和当前结点的下一个结点) listnode *reverselist(listnode *head) { if(head==NULL) return NULL; listnode *now=head->next;//当前结点 listnode *newhead=(listnode *)malloc(sizeof(listnode));//新结点的头指针 newhead->next=NULL; //只有一个结点,头结点(空) if(now==NULL) return head; listnode *pre=NULL;//当前结点的前一个结点 while(now !=NULL) { listnode *pnext=now->next; //保存当前结点的下一个结点 //如果当前结点的下一个结点为空,则构建新的头结点 if(now->next==NULL) { newhead->next=now; } //将当前结点的next指向它的前一个结点 now->next=pre; //pre和now指针都后移 pre=now; now=pnext; } return newhead; }
测试代码以及运行结果:
int main() { listnode *head=init(); print(head); head=reverselist(head); print(head); return 0; }