单向链表逆序的3种实现

【遍历实现】

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 最好也标号。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值