您的位置:首页 > 其它

逆序链表小范例

2014-04-10 23:03 176 查看

(弱弱小题,闲的没事你就看看吧)

今天晚上跟老L聊天,看到一个关于逆序链表的题目。两人吃完饭正好练练手,比速度,结果写完之后发现问题不少。

要求:仅仅是实现逆序链表。

先过目一下最初的源码

#include <iostream>
//#include <vld.h>
using namespace std;

//定义ListNode链表数据
typedef struct _ListNode{
int data;
_ListNode* nextNode;
_ListNode(){
nextNode = NULL;
}
}ListNode;

//显示函数 链表函数
void Display (ListNode* pHead)
{
if ( !pHead)
{
printf("空表\n");
return;
}
ListNode* ptmp = pHead;
while(ptmp)
{
printf("%d " ,ptmp->data);
ptmp = ptmp->nextNode;
}
printf("\n");

}

//逆序链表
void ReserveList( ListNode* pPHead)
{
if ( !pHead)
return ;
ListNode* first = pHead->nextNode;
if ( !first )
return ;

ListNode* temp;
pHead->nextNode = NULL ; //先断开父子关系,避免乱了辈分这一说
while(first)
{
temp = first->nextNode; //先把孙子放别人家
first->nextNode = pHead ; //然后儿子在家造反,倒指老爹
pHead = first; //儿子在家变老大
first = temp; //再把孙子抱回家,然后孙子重走儿子的路
}
}
int main()
{
ListNode* pHead = new ListNode;
ListNode* ptmp = pHead;
int iMax = 1;
for (int index = 0 ; index < iMax ; index++)
{
ptmp->data = index + 1 ;
if(index<iMax-1)
ptmp->nextNode = new ListNode;
ptmp = ptmp->nextNode;
}

Display(pHead);
ReserveList(pHead);
Display(pHead);
return 0 ;
}
看上去好像很不错的样子,ctrl+F5:

好嘛,有问题。再跟踪调试,跟踪到Reserve函数中,发现Reserve函数结束完成之后,pHead确实是翻转了,那为什么没显示出来了!

在老L的慧眼下,一下发现了端倪,Reserve的确实有问题,Reserve的参数是个局部变量(多基础、多简单的问题!)。

这里我错误了想当然了:指针的值可改。

虽然这里是指针,但是能该的是指针所指向的地址,而不是指针本身。考虑升级有两种方式:

//逆序链表
void ReserveList( ListNode** pHead)
void ReserveList( ListNode* &pHead)
第二种,看起来怪怪的是吧,还是用第一种吧:二级指针,这样就能改指针本身了。

对比了老L的代码,发现他使用了另一种方式,不该头指针,链表自带头结点(第一个数据不是链表有效数据,仅仅做个链表头)。

这是标准链表么?是我太久没看数据结构了么?应该是兼容各种风格吧,还是看看老严的《数据结构》吧,其中说到:有时,我们会在单链表的第一个节点之前附设一个节点,称为头结点。看来这是部分人使用标志。这样的好处是能保证头结点的稳定性,比如我们要删除第一个节点不需要改变首地址,或者像本程序中这样,不需要变化指针本身的值。

最后记得释放内存,做个优秀的程序编写者,不能内存泄露

//销毁链表
void Destroy(ListNode * pHead)
{
if( !pHead )
return;
if ( pHead->nextNode )
{
Destroy(pHead->nextNode);
}
delete pHead;
pHead = NULL ;
}


最后的代码:
//逆序链表
void ReserveList( ListNode** pPHead)
{
ListNode* pHead = *pPHead;
if ( !pHead)
return ;
ListNode* first = pHead->nextNode;
if ( !first )
return ;

ListNode* temp;
pHead->nextNode = NULL ; //先断开父子关系,避免乱了辈分这一说
while(first)
{
temp = first->nextNode; //先把孙子放别人家
first->nextNode = pHead ; //然后儿子在家造反,倒指老爹
pHead = first; //儿子在家变老大
first = temp; //再把孙子抱回家,然后孙子重走儿子的路
}
*pPHead = pHead;
}

int main()
{
ListNode* pHead = new ListNode;
ListNode* ptmp = pHead;
int iMax = 10;
for (int index = 0 ; index < iMax ; index++)
{
ptmp->data = index + 1 ;
if(index<iMax-1)
ptmp->nextNode = new ListNode;
ptmp = ptmp->nextNode;
}

Display(pHead);
ReserveList(&pHead);
Display(pHead);
Destroy(pHead);
return 0 ;
}好像还不错的样子

 怎么有种像当年较数据结构的作业一样

,看官随便看看吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: