您的位置:首页 > 其它

链表的循环链接

2012-09-04 22:10 337 查看
问题1:判断链表是否循环?

解析:

设置1个快指针(每次向前走2个节点),一个慢指针(每次向前走1个节点),如果存在环,则快指针肯定能赶上慢指针;

简单代码:

bool isLoopList(const ListNode* root)

{

if(root == NULL) return false;

const ListNode *pFast = root,*pSlow = root;

while(true)

{

if(pFast->next == NULL) return false;

pFast = pFast->next->next;

pSlow = pSlow->next;

if(pFast == pSlow) return true;

}

}

简单测试:

const int N = 10;

string tmp("A");

ListNode* root = new ListNode;

root->value = tmp;

tmp += 'A';

ListNode* cur = root,*loopNode = NULL;

int i = 0;

while(i <= N)

{

InsertAfter(cur,tmp);

tmp += 'A';

cur = cur->next;

if(i==3)//测试用例,设定循环开始节点为3

loopNode = cur;

++i;

}

cur->next = loopNode;//循环链表

if(isLoopList(root)) cout<<"Loop List.\n";



问题2:找循环单链表的开始循环节点,如A->B->C->D->E->C,则C为开始循环节点。不存在循环则返回NULL;

简单代码:

const Node* LoopStart(const Node* root)

{

if(root==NULL) return NULL;

const Node *slow=root,*fast=root;

while(fast->next)

{

slow = slow->next;

fast = fast->next->next;

if(slow == fast)//相遇节点

break;

}

if(fast->next == NULL) return NULL;

//slow重新到头部节点,slow和fast再次相遇的节点必定是循环开始节点

slow = root;

while(slow != fast)

{

slow = slow->next;

fast = fast->next;

}

return fast;

}

简单测试代码:

const int N = 10;

string tmp("A");

ListNode* root = new ListNode;

root->value = tmp;

tmp += 'A';

ListNode* cur = root,*loopNode = NULL;

int i = 0;

while(i <= N)

{

InsertAfter(cur,tmp);

tmp += 'A';

cur = cur->next;

if(i==3)//测试用例,设定循环开始节点为3

loopNode = cur;

++i;

}

cur->next = loopNode;//循环链表

const ListNode* start = LoopStart(root);

if(start != NULL)

cout<<"Loop Start Node : "<<start->value<<endl;

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: