单链表逆序作为常见的数据操作,具体实现有不同的版本,但是总归需要考虑输入结点为空、一个结点和多个结点的情况。
该逆序思想来自《剑指offer》;另外一个容易想到的逆序方式是,申请一个头结点head,然后把待逆序结点顺序插入到头结点后head->next,最后返回head->next即可。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
Node* create_list(int *array,const int length)
{
if(array==NULL)
{
return NULL;
}
if(length<=0)
{
return NULL;
}
Node *head = (Node*)malloc(sizeof(Node));
head->data = array[0];
head->next = NULL;
Node *p ,*q = head;
for(int i=1;i<length;i++)
{
p = (Node*)malloc(sizeof(Node));
p->data = array[i];
q->next = p;
q = p;
}
q->next = NULL;
return head;
}
Node *reverse(Node *head)
{
// 1 --> 2 --> 3 --> 4 -->... --> NULL
//
//NULL <-- 1 <-- 2 3 --> 4 -->... --> NULL
// prev cur next
Node *prev; //指向已逆序的顶端
Node *cur; //指向待逆序的首端
Node *next; //指向待逆序的首端的下一个结点
if(head==NULL)
{
return NULL;
}
cur = head->next;
prev = head;
prev->next = NULL; //头结点变尾结点,next置空
while(cur!=NULL)
{
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
void print(Node *head)
{
Node *p = head;
while(p!=NULL)
{
fprintf(stdout,"%d ",p->data);
p = p->next;
}
}
int main(void)
{
int a[] = {3,5,6,7,7,83,23};
const int len = sizeof(a)/sizeof(int);
Node *head = create_list(a,len);
print(head);
printf("\n");
Node *rev = reverse(head);
print(rev);
printf("\n");
return 0;
}