反转链表的几种方法
- 就地逆序,用前驱、后驱结点分别保存链表目前结点的前面后面的结点,便于节点的指向(最基本操作)
- 递归法,递归掌握不好的要自己Debug去了,主要理解就好
- 插入法,用第二个有数据结点和后面的结点不断插向头结点的下一个节点前面,只用两个变量
各种方法把对应的注释取消后查看
源代码如下
/*链表逆序 */
/*例如输入1 2 3 4 5,输出5 4 3 2 1*/
#include<stdio.h>
#include<stdlib.h>
typedef struct Lnode *List;
struct Lnode{
int data;
List Next;
};
List ReadList();
/* 第一种就地逆序 */
List Reverse1(List L);
/* 第二种 递归逆序 */
void recursiveReverse(List *firstRef);//需要传入头结点的指针
void Reverse2(List *headRef);
/* 第三种 插入法 */
void Reverse3(List L);
/* */
void PrintList(List L);
void freeList(List L);
int main()
{
List L1,L2;
L1=ReadList();
printf("Reverse before\n");
PrintList(L1);
/* 第一种 */
/* L2=Reverse1(L1);
printf("Reverse after\n");
PrintList(L2);
freeList(L2); */
/* 第二种 */
/* Reverse2(&L1);
printf("Reverse after\n");
PrintList(L1); */
/* 第三种 */
Reverse3(L1);
printf("Reverse after\n");
PrintList(L1);
return 0;
}
List ReadList()
{
int i,N,temp,x;
List head=(List )malloc(sizeof(struct Lnode));
head->Next=NULL;
List p,pre=head;
printf("Please input number:");
scanf("%d",&N);
printf("Please input equal number(s):");
for(i=1;i<=N;i++)
{
scanf("%d",&x);
p=(List )malloc(sizeof(struct Lnode));
p->data=x;
p->Next=NULL;
pre->Next=p;
pre=p;
}
return head;
}
void PrintList(List L)
{
List p=L->Next;
int flag=1;
while(p)
{
if(flag)
flag=0;
else
printf(" ");
printf("%d",p->data);
p=p->Next;
}
printf("\n");
}
void freeList(List L)
{
List p=L->Next;
List temp;
while(p)
{
temp=p;
p=p->Next;
free(temp);
}
free(L);
}
/* 第一种 */
/* 就地逆序,使用前中后驱结点 */
/* 保存链表当前位置的不同位置 */
/*
List Reverse1(List L)
{
List pre,p,New;//前中后驱结点
p=L->Next;
New=p->Next;
p->Next=NULL;
pre=p;
p=New;
while(p->Next)
{
New=p->Next;
p->Next=pre;
pre=p;
p=New;
}
p->Next=pre;
L->Next=p;
return L;
}
*/
/* 第二种,迭代法 */
/* 尤其要注意理解迭代的过程 */
/*
void recursiveReverse(List *firstRef)
{
if(firstRef==NULL||*firstRef==NULL)
return;
List cur,rest;
cur=*firstRef;
rest=cur->Next;
if(rest==NULL)
return;
recursiveReverse(&rest);
cur->Next->Next=cur;//注意此句是让cur的下一个节翻转回来指向自己
cur->Next=NULL;//然后让自己的的下一个节点指向NULL
//等待下一轮迭代
*firstRef=rest;
}
void Reverse2(List *headRef)
{
if(*headRef==NULL||(*headRef)->Next==NULL)
return;
List firstNode=(*headRef)->Next;
recursiveReverse(&firstNode);
(*headRef)->Next=firstNode;
}
*/
/* 第三种 插入法 */
/* 遍历插入 */
void Reverse3 (List L)
{
if(L==NULL||L->Next==NULL)
return;
List cur;
List New;
cur=L->Next->Next;
L->Next->Next=NULL;
while(cur)
{
New=cur->Next;
cur->Next=L->Next;
L->Next=cur;
cur=New;
}
}