【遍历实现】
Node *reverse(Node *list)
{
link t, y = list, r = 0;
while (y != 0) { t = y->next; y->next = r; r = y; y = t; }
return r;
}
其实上面的这个操作自然地对应于栈的出栈/压栈操作.
【基于栈思想的实现】
// 1. 判断栈是否为空
bool isEmpty(Node* stack)
{
return (stack == NULL);
}
// 2. 向栈stack中压入一个node元素
void push(Node* &stack, Node* node)
{
node->next = stack;
stack = node;
}
// 3. 从栈stack中弹出一个元素
Node* pop(Node* &stack)
{
assert(!isEmpty(stack));
Node *t = stack;
stack = stack->next;
return t;
}
Node *reverse(Node *oldList)
{
Node *newList = NULL;
while(!isEmpty(oldList))
{
push(newList, pop(oldList));
}
return newList;
}
【递归实现】
List* rev( List * head )
{
List *rHead;
if( !head )
{
return head;
}
else if( !head->next ) //只有一个结点
{
return head;
}
else
{
//
rHead = rev( head->next );
head->next->next = head;
head->next = NULL;
return rHead;
}
}
递归时,head分别用 head head1,head2 ...headn-1, headn来表示(共n+1)个节点
rHead = rev( head->next ); 此句的递归一直将参数传进来的
List * head 递归到 headn 然后判断
else if( !headn->next )
{
return headn;
}
将返回值给rHead,此时rHead指向链尾,由于在此次返回,故此次没有执行最后的else的那部分的语句,返回上一级即是 headn-1 那一级,继续执行
下面的 headn-1->next->next = headn-1;
headn-1->next = NULL; //此两句将最后两个逆序连接,
return rHead; //之后返回rHead比上一层的rHead即是执行
rHead = rev( head->next )赋值,因为递归的
口都是在这里的,如果说好理解点也可以将rHead
来编号
同理
在返回rHead后,继续执行
headn-2->next->next = headn-2;
headn-2->next = NULL;
return rHead;
.....
一直到 head时 即是原链表的第一个节点,在对其head->next = NULL,
后,此时以 rHead 所指向的节点为链头的逆序链表就形成了.最好的理解就是你将递归时,head分别用 head head1,head2 ...headn-1, headn来编号表示就好理解的拉,对于 rHead 最好也标号。
460

被折叠的 条评论
为什么被折叠?



