1、针对单链表,当我们进行操作时,如果需要进行反转或者进行其他操作时,有链表断开的情况,不妨考虑下使用辅助指针来记录断开后的链表位置,将需要处理的数据处理好后,可以使用此辅助指针找到链表的位置
#include <stdlib.h>
/*
两个一组的反转链表,用到的也是使用辅助指针,当反转的过程中,一定会将链表断开。
如果我们想要找到接下来的链表,就需要事先记住断开的点位,前面的反转完后,再给它链接起来。再将头结点的位置往后移动。
比如下面,使用带头结点的方式更便于对链表进行操作和移动指针。
*/
typedef struct Node{
int val;
struct Node * next;
}Nodes, *Linklist;
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,是因为下面遍历数据所用的是直接打印结点数据,需要从头结点下一个开始
}
Linklist coupleReverse(Linklist head){
Linklist curr = head;
Linklist tmp = curr->next;
Linklist tmp1 =curr->next->next->next;
while(curr->next != NULL &&curr->next->next != NULL)
{
//方式一,参考代码随想录结果
// Linklist tmp = curr->next;
// Linklist tmp1 =curr->next->next->next; //这个注释行感觉也可以,不过循环初始化新结点指针的话,总感觉会浪费空间,所以使用下面的方式了
// curr->next = curr->next->next;
// curr->next->next = tmp;
// curr->next->next->next = tmp1;
// curr = curr->next->next;
//方式二
tmp = curr->next;
tmp1 =curr->next->next->next; //这两行如果放在后面执行的话,就会出错,导致段错误,应该是超出链表空间了,下个例子测试下。
curr->next = curr->next->next;
curr->next->next = tmp;
tmp->next = tmp1;
curr = curr->next->next;
}
return head;
}
Nodes * display(Nodes * head){
if(head == NULL){
exit(1);
}
Nodes * phead = head;
while(phead != NULL){
printf("%d ",phead->val);
phead = phead->next;
}
printf("\n");
}
int main(){
int arr[] = {1,2,3,4,5,6,7,9};
int size = sizeof(arr)/sizeof(arr[0]);
Linklist head = initLinkList(arr,size);
Linklist reverseHead = coupleReverse(head);
display(reverseHead->next);
return 0;
}