Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1714448
  • 博文数量: 177
  • 博客积分: 9416
  • 博客等级: 中将
  • 技术积分: 2513
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-06 16:08
文章分类

全部博文(177)

文章存档

2013年(4)

2012年(13)

2011年(9)

2010年(71)

2009年(12)

2008年(11)

2007年(32)

2006年(25)

分类:

2009-11-27 11:24:28

Recursion is great to resolve many problems including reverse of a linked list. First let's check the non-recursive version of reverse.

To reverse a linked list, we start from the head (in this essay we will use linked list without extra head node). One way is to use a stack, pushes all nodes started from head to the last one. Then pops all nodes and appends them to the reversed list. The way is simple but not straightforward. And it's not simple enough and occupies extra space. If the size of list is very large, the space efficiency is poor. Also the time consumed contains 1. traverse the whole list to push all nodes into stack, and 2. traverse the whole stack (which is the whole list, again) and construct the new list.

So we consider another way. Here we don't need any extra spaces and only need to traverse the list once. It can be demonstrated as following:

 |prev  |cur  |next
 v      v     v
       ---   ---   ---         ---
NULL   | |-->| |-->| |-->...-->| |-->NULL
       ---   ---   ---         ---

                    I

              3     5
       2|prev |cur  |next
        v     v     v
       ---   ---   ---         ---
NULL<--| |<--| |   | |-->...-->| |-->NULL
     1 --- 4 ---   ---         ---

                    II
OK, let's check the code.

The definition of node:

struct LinkedList
{
    int v;
    LinkedList* n;
};


Auxiliary function to append a node to the list and can be used to construct a new list:

LinkedList* Append(LinkedList* aList, LinkedList* aNode)
{
    if (!aList) return aNode;
    LinkedList* temp = aList;
    while (temp->n) temp = temp->n;
    temp->n = aNode;
    aNode->n = NULL;
    return aList;
}


Other functions such as insert a node are not listed here because they are not used.

As illustrate in the diagram above, 5 steps need to reverse 2 nodes:

LinkedList* Rev(LinkedList* aList)
{
    if (!aList) return NULL;
    LinkedList* prev = NULL;
    LinkedList* cur = aList;
    LinkedList* next = aList->n;
    while (next)
    {
        cur->n = prev;
        prev = cur;
        cur = next;
        next = next->n;
        cur->n = prev;
    }
    return cur;
}


Now we consider the recursive way:

if next node not null
    then reverse the list starts from next node and save the reversed list;
else
    append the node to the reversed list started from next node and return the whole list;


It's easy to implement the reverse:

LinkedList* RevRecur(LinkedList* aList)
{
    if (!aList) return NULL;
    if (aList->n)
        aList->n = RevRecur(aList->n);
    return Append(aList->n, aList);
}


阅读(3448) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

fera2009-12-24 09:35:22

updated. Thanks. You are still using 'qzhenha', hah.

chinaunix网友2009-12-23 20:59:53

Recursion is great to resolve many problems including reverse of a lined list. linked list????????