一、双指针反转链表的关键点是,
一定要创建一个结点去保存当前结点的下一个结点。就好像下面的afterp ,有了它,我们就可以在反转前面的结点后,还能找到接下来的链表。
接上一篇链表部分操作案例-优快云博客
# include <stdio.h>
# include <stdlib.h>
typedef struct Node{
int val;
struct Node * next;
}Nodes, *Linklist;
Nodes* reverseList(Nodes* head){ //这里直接使用首元结点的地址作为头指针,第一个结点就是带数据的。
Nodes *prev = NULL;
Nodes *curr = head;
Nodes * afterp;
if(head == NULL){ //
exit(1);
}
while(curr != NULL){
afterp = curr->next;
curr->next = prev;
prev = curr;
curr = afterp;
}
return prev;
}
Nodes * initLinkList(int arr[], int size){
if(arr == NULL){
exit(1);
}
Nodes *head = (Nodes *)malloc(sizeof(Nodes));
head ->next= NULL; //这里创建的是头结点,头指针head
Nodes * p = head;
int i=0;
while(i < size){
Nodes *newNodes = (Nodes *)malloc(sizeof(Nodes));
newNodes->next=NULL;
newNodes->val = arr[i];
p->next = newNodes;
p = newNodes;
++i;
}
return head->next; //至于这里返回next,是因为下面遍历数据所用的是直接打印结点数据,需要从头结点下一个开始
}
Nodes * display(Nodes * head){
if(head == NULL){
exit(1);
}
Nodes * phead = head; //如果在这里设定head的位置也可以,phead直接指向首元素结点也就是 head->next;
while(phead != NULL){
printf("%d ",phead->val);
phead = phead->next;
}
printf("\n");
}
int main(){
int arr[] = {1,2,1,3,5,6,7,9};
int size = sizeof(arr)/sizeof(arr[0]); //这个式子不要直接做库函数的参数,在main中计算出来再用就行了
Nodes*head = initLinkList(arr,size);
display(head);
Nodes * p2 = reverseList(head);
display(p2);
return 0;
}