链表的逆置之头插法:
头插法的核心思想就是先把当前的链表切分为两个部分,第一个部分为只有一个头节点的单链表,第二个部分是除头节点外的剩余所有的链表,挨个把第二部分的节点插入到第一个部分中,插入的方法是运用建立单链表的头插法,其刚好可以起到逆置的作用。
此方法的空间复杂度为O(1)
代码如下:
void reverse(LinkList *L) { LinkList *p=L->next,*q;//p指向的是L的首节点 L->next=NULL;//重新设定L是一个带头节点的空表 while(p!=NULL) { q=p->next;//设定q为p的后继节点 q->next=L->next;//头插法将q插入到L的后面 L->next=q;//头插法 p=q;//q后移,继续头插法直到p为空 } }
完整的测试代码:
#include<stdio.h> #include<stdlib.h> typedef struct node{ int data; struct node *next; }Node; void creat_linkList(Node *L){ //尾插法 Node *rear=L; for(int i=0;i<10;i++) { Node *node=(Node *)malloc(sizeof(Node)); node->data=i; node->next=NULL; rear->next=node; rear=node; } } void reverse(Node *L) { Node *p=L->next; L->next=NULL; Node *q=NULL; while(p!=NULL) { q=p->next;//定义一个在p后面的节点为q p->next=L->next;//L的next指的是p原先的位置,现在需要p回头指向自己原先指定的位置 L->next=p;//再让L的next记录当前p的位置,方便p往后移后,新的p可以回头指自己先前的位置达到逆转的作用 p=q;//p再转到下一个位置 } } int main(){ Node L; L.data=1000; L.next=NULL; creat_linkList(&L); reverse(&L); Node *p=L.next; while(p!=NULL) { printf("%d ",p->data); p=p->next; } }