昨天看CSDN的一个文章提到,某公司面试时问到单向链表的反转问题,有好多程序员答不出来。以前我也没做过类似的题目,试着写了一下。
问题描述:已知一个单向链表,写一个函数,使得该链表的方向反转,即头变尾,尾变头,指示方向相反。
分析:该问题可以有两种方法,一是交换首尾两个节点的数据,而不改变其内存的存储结构,二是改变所有节点的指向下一个节点的指针。显然第二种方法更加有效。
/×链表的定义和一些操作*/
typedefstructlist
{
intno;
structlist*pNext;
}list;
list*listinit(intcount)
{
list*pHead;
list*pList;
intno=0;
pHead=malloc(sizeof(list));
pHead->no=no;
pList=pHead;
while(count--)
{
pList->pNext=malloc(sizeof(list));
pList=pList->pNext;
pList->no=++no;
}
pList->pNext=NULL;
returnpHead;
}
voidlistrelease(list*pHead)
{
list*pList=pHead;
list*pNext;
//free((char*)pHead);
//return;
while(pList!=NULL)
{
pNext=pList->pNext;
free(pList);
pList=pNext;
}
}
/*链表反转的算法,其实很简单*/
list*listreverse(list*pHead)
{
list*pList=pHead;
list*paPre=NULL;
list*paNext=NULL;
do
{
paNext=pList->pNext;
pList->pNext=paPre;
paPre=pList;
pList=paNext;
}while(pList!=NULL);
returnpaPre;
}
/*这是测试用的函数*/
voidlistshow(list*pHead)
{
list*pList=pHead;
while(pList!=NULL)
{
printf("list=%d/n",pList->no);
pList=pList->pNext;
}
}
intmain()
{
list*pHead=listinit(10);
printf("beforereverse:/n");
listshow(pHead);
pHead=listreverse(pHead);
printf("afterreverse:/n");
listshow(pHead);
listrelease(pHead);
return0;
}
运行结果:
beforereverse:
list=0
list=1
list=2
list=3
list=4
list=5
list=6
list=7
list=8
list=9
list=10
afterreverse:
list=10
list=9
list=8
list=7
list=6
list=5
list=4
list=3
list=2
list=1
list=0