Life is Good.

Enhance Tech and English
随笔 - 65, 文章 - 20, 评论 - 21, 引用 - 0
数据加载中……

单线链表常见操作

1.单线链表倒序/逆序:
struct Node
{
    int data;
    Node* next;
};

Node* Reverse(Node* head)
{
    struct Node *prep,*nowp,*nextp;

    prep=NULL;
    nowp=head;

    while(nowp!=NULL)
    {
        nextp=nowp->next;
        nowp->next=prep;
        prep=nowp;
        nowp=nextp;
    }

    return prep;
}

2. 判断单向链表是否有环。下图的三种情形都视为有环,算法必须能处理它们。


01) 如果知道链表长度, 则可以遍历链表, 遍历次数大于长度, 就是有环了

   int iLength; 链表长度, 已知
   int i = 0;
   while (p != NULL)
   {
       i ++;
       if (i > iLength)
       {
           break;
           return;
       }
   }

02)解法:设置两个指针,一个每次向前跳一步,一个跳两步,如果它们相遇,则有环。


bool fLinkedListHasCircle(const Node* p)
{
 bool flag = false;
 
 const Node* slowIterator = p;
 const Node* fastIterator = p;

 while(slowIterator && fastIterator->next)
 {
  slowIterator = slowIterator->next;
  fastIterator = fastIterator->next->next;
  if (slowIterator == fastIterator)
  {
   flag = true;
   break;
  }
 }
 return flag;
}

快速证明算法的正确性:

考虑一般的情形,假设环上有n个结点,把它们从0到n-1编号,假设slowIterator达到节点0时,fastIterator领先 slowIterator的距离为m,我们知道fastIterator在一圈之内必能追上slowIterator。假设x跳以后 fastIterator追上slowIterator,此时slowIterator所在的结点编号为x,而fastIterator所在的节点编号为 m+2x-n:

x = m+2x-n
x = n-m

所以经过n-m跳后,fastIterator追上slowIterator。


posted on 2010-10-19 16:26 Mike Song 阅读(245) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理