单向链表

HowWhatWhy 2004-08-08 04:37:12
如何不要用到额外的资源就把一个单向链表倒序排列
...全文
368 点赞 收藏 21
写回复
21 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
jemmy 2005-08-31
list *pHead;

list *p;

p=NULL;

while(pHead)

{

list *q=pHead->next;

pHead->next=p;

p=pHead;

pHead=q;

}

pHead=p;
回复
xiongbing528 2005-08-03
if(L==null) return;
p=L->next;
if(p==null) return;
q=L->next;
if(q==null) return p;
while(q->next)]
{
r=q;
q->next=p;
p=r;
q=q->next;}
q->next=p;
P->next==null;
L=P;
回复
juipter 2005-07-21
首先把头接点截下来,然后把它的指针域置空,然后分别把首元结点开始,到尾结点为止,分别倒置,就完成了
回复
Smile_Tiger 2005-07-12
伪码而已,不必认真,倒是偷懒想直接使用贴出来的代码,脸红的
回复
gordonstysty 2005-07-12
建议大家的程序先debug ok了再贴上来,error的code贴上来,脸红的
回复
zhuoranmcsd 2004-11-01
这个问题很简单啊,我没有看前面给出的算法,下面给一个很简单的思路:

1、假设单链表有头结点,指针L指向头结点
2、设置两个指针P、Q分别指向L->next和L->next->next
3、将P->next设空
4、(开始循环)将Q所指结点插入到头结点后,Q向后移(直到Q->next==NULL结束循环)
5、OVER

只是完成一个插入的工作
需要说明的是,在程序中需要另外设置一个指针S,指向Q->next,以保证操作的实现

下面是算法:

void reserve(LinkList &L)
{
p=L->next;
q=p->next;
s=q->next;
p->next=NULL;
while(s)
{
q->next=L-next; L->next=q;
q=s;s=s->next;
}
}
回复
edward88cn 2004-10-29
什么都不用就想倒序排列,除非你是魔术师。上面的的算法都不错,绝对没有用到额外的资源
回复
Leaveye 2004-10-14
唉,本质还都是一样。绝对的不另要空间的操作价值没有那么大了。
这是一个稳定性比较好的算法:
ListNode * Reverse(ListNode * pHead) {
ListNode * pTmp, pNewHead = '\0';
if(!pHead) return pHead;
while(pHead) {
pTmp = pHead->next;
pHead->next = pNewHead;
pNewHead = pTmp;
}
return pNewHead;
}
回复
寻开心 2004-08-19
很抱歉
前面给出的算法有问题,不能实现翻转功能
解决这个问题,要分两步,第一步是不约束变量的使用,看看如何解决这个问题

假定有三个变量 pLast, pCur 和pNext,
其中pCur, 表示当前处理的节点, pLast 表示上一个节点,初始就是NULL
while ( pCur ) {
pNext = pCur->next; // 保存下一个位置
pCur->next = pLast; // 翻转指针,指向上一个位置
pLast = pCur; // 重置上一个位置的变量
pCur = pNext; // 当前指针下移
}
这样就可以完成翻转操作了。

第二步,我们看看那些变量可以简化掉
这就要利用链表的头 和 尾两个指针了
原来的头指针的next指针处理完成后,变成了NULL
而原来的尾指针的Next,在处理的中间过程是无用的,可以拿来使用
因此这两个东西都可以用来做特殊处理使用,
而pCur指针是可以作为参数传递进来使用的,

Reverse(List* pCur, List* pHead, List * pTail)
{
pTail->next = pHead;
pCur = pHead->next;
while ( pCur != pHead ) { // 因为初始化尾指针的next指针为pHead了,这就是结束条件
pHead->next = pCur->next;
pCur->next = pTail->next;
pTail->next = pCur;
pCur = pHead->next;
}
pHead->next = NULL;
}

在调用前的准备工作
CList * pList;
CList * pTail;
Reverse(pList, pList, pTail);

为了找到尾指针,还需要补充一个函数
List * FindTail(List *pList)
{
while ( pList->next != NULL ) {
pList = pList->next;
}
return pList;
}

补充,尾指针是必须要的
否则,当链表翻转操作完成后,就找不头了(因为头已经变成了尾部)
还使用原来的头指针就无法再遍历链表了

这样整个完整的操作就是:
CList *pList, pTail;
..... //初始化 pList;
pTail = FindTail(pList);
Reverse(pList, pList, pTail);
此后再用链表就要用pTail而不是pList了
回复
Leaveye 2004-08-17
恩。。补充一下:上面这个“类比”也许有点不太恰当。一时也想不出更好的类比了。。
回复
Leaveye 2004-08-17
让用2个指针就可以,效率不高,方法感觉有点类似9连环的解法。
其实1个指针也行,但是效率更低,比9连环还复杂。
:(
回复
寻开心 2004-08-17
非递归的版本:
Reverse(List * pList, List * pHead)
{
while( pHead->next )
{
pHead->next = pList->next;
pList->next = pList;
pList = pHead->next;
}
}
使用
CList * pList;
Reverse(pList, pList);
看似没有利用资源,实质还是利用了——函数的入口参数

真正的一个也不利用可能吗?

回复
寻开心 2004-08-17
// 写一个递归形式的
class List
{
DataType data;
List * pNext; // next list element
}

// pCur 要处理的链表的位置, pHead就是这个链表的头
Inverse(List* pCur, List* pHead)
{
if ( pCur->next == NULL ) {pCur->next = pCur; pHead->next=NULL; return; }
pHead->next = pCur->next;
// 头指针的next指针在翻转后,设置为NULL,没有用,可以用来做临时变量。
// 保存下一个位置
pCur->next = pCur;
// 把当前指针反转向上一个位置
Inverse(pHead->next, pHead);
// 处理后一个
}

使用的时候
List * pList;
Inverse(pList, pList); // 就可以了。

基本原理就是利用头指针的next指针作为
回复
HowWhatWhy 2004-08-17
谁能回答一下呢
回复
ZhangYv 2004-08-09
问过无数次的问题了,你可以GOOGLE之类搜现成的程序。
回复
HowWhatWhy 2004-08-09
这谁不会说呀
具体程序怎么写呢

楼上没必要把题目重复一遍
回复
jazy 2004-08-09
现有m1~m5
m1.next = m2,m2.next = m3,m3.next = m4,m4.next = m5,m5.next = NULL
变成m5~m1只要写:
m5.next = m4;
m4.next = m3;
m3.next = m2;
m2.next = m1;
m1.next = NULL;
回复
HowWhatWhy 2004-08-09
我找不到啊
要求没有额外资源的
楼上帮帮忙吧
回复
zhengwei1984222 2004-08-09
无法实现
回复
HowWhatWhy 2004-08-08
说得容易 怎么改啊
回复
加载更多回复
相关推荐
发帖
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2004-08-08 04:37
社区公告
暂无公告