검출기 사이클에서 계보 그래프 중에 깊이 첫 번째 검색
-
05-07-2019 - |
문제
나는 말로드 계 재귀적으로 데이터.어떤 잘못된 데이터 세트 내 재귀지...고 있기 때문에 사이클 데이터에 있습니다.
를 어떻게 감지하는 그들 사이클을 중지 반복되는?
내가 생각하는 동안 반복되는 유지한 hashTable 으로"모두를 방문한"말입니다.하지만 그 일부를 찾을 것입니다양성기 때문에 말할 수 있습에서 두 번 나무입니다.
무슨 일어날 수 없다는 말로 나타나 아버지나 할아버지나 할아버지의 자체입니다.
해결책
의사 코드:
void ProcessTree(GenTreeNode currentNode, Stack<GenTreeNode> seen)
{
if(seen.Contains(currentNode)) return;
// Or, do whatever needs to be done when a cycle is detected
ProcessHorse(currentNode.Horse); // Or whatever processing you need
seen.Push(currentNode);
foreach(GenTreeNode childNode in currentNode.Nodes)
{
ProcessTree(childNode, seen);
}
seen.Pop();
}
기본적인 아이디어의 목록을 유지하기 위해 모든 노드는 우리는 이미 우리의 방법은 현재 노드경우 다시 얻을 노드 이미 우리가 갔을 통해,당신은 알고 있는 우리가 형성기(그리고 우리 건너 가치,또는 할 필요가 무엇이든 할 수)
다른 팁
유지의 스택 모든 요소를 선도하는 루트의 나무입니다.
때마다 당신은 사전에 나무 아래로,스캔 스택에 대한 아이는 요소입니다.일치하는 항목을 찾으면,다음을 발견하신 루프를 건너뛰는 아이입니다.그렇지 않으면,아이를 밀어 스택에고 진행합니다.때마다 당신이 뒤 트리,팝 요소를 더하고 버린 것입니다.
(의 경우에는 계보,데이터는"아동"노드 트리에 있는 아마도 생물 부모의"부모"노드입니다.)
이 소리를 좋아하는 경우를 수 있는 마지막으로 적용되는 인터뷰 퀴즈 문제는:을 찾아주기에 연결 목록을 사용하여 만 O(1)메모리입니다.
이 경우에 당신의"링크"목록은 시퀀스의 요소를 열거.사용자 실행 중 하나에 의 경우 빠른 속도로 느리게 한 다음이 있습니다.이것은 또한 수 O(n)시간 대신에 O(n^2)필요한 시간을 확인하는'보'목록입니다.단점은 당신에 대해 알아 루프의 노드로 처리되었습니다.
예에서 나는 교체는'반도'방식으로 간단에서 쓰고 있는'드롭 마커의 방법입니다.
class GenTreeNode {
...
///<summary>Wraps an the enumeration of linked data structures such as trees and linked lists with a check for cycles.</summary>
private static IEnumerable<T> CheckedEnumerable<T>(IEnumerable<T> sub_enumerable) {
long cur_track_count = 0;
long high_track_count = 1;
T post = default(T);
foreach (var e in sub_enumerable) {
yield return e;
if (++cur_track_count >= high_track_count) {
post = e;
high_track_count *= 2;
cur_track_count = 0;
} else if (object.ReferenceEquals(e, post)) {
throw new Exception("Infinite Loop");
}
}
}
...
///<summary>Enumerates the tree's nodes, assuming no cycles</summary>
private IEnumerable<GenTreeNode> tree_nodes_unchecked() {
yield return this;
foreach (var child in this.nodes)
foreach (var e in child.tree_nodes_unchecked())
yield return e;
}
///<summary>Enumerates the tree's nodes, checking for cycles</summary>
public IEnumerable<GenTreeNode> tree_nodes()
{
return CheckedEnumerable(tree_nodes_unchecked());
}
...
void ProcessTree() {
foreach (var node in tree_nodes())
proceess(node);
}
}
매우 간단하는지 확인하는 방법을 이해하는 제 자체:
무엇을 수 없는 일이 생긴다는 말로 나타나 아버지나 할아버지 또는 greatgrandfather 의 자체입니다.
때마다 당신이 삽입하는 노드의 트리,트래버스 트리를 뿌리는 것을 확인하는 말로 존재하지 않는 모든 종류의 부모입니다.
하이 속도 연결할 수 있습니다 hashtable 각 노드에,당신이 캐쉬의합니다.다음을 검색하지 않아도 전체 경로는 다음 시간 당신에 삽입하는 말에서는 노드입니다.
의 해시 테이블 솔루션을 작동하는 경우 추적할 수의 노드 대림 마스터 tv 를 계속 시청해 주세요.그냥 있는지 확인을 읽을 때마다 새로운 말을 만든 새로운 노드의 값이 있는 경우/말과 같은 이전 노드의 값/말입니다.
당신 directed acyclic graph, 지 않습니다.이 없을 것으로 주기 말의 후손할 수 없는 또한 그것의 조상이라고 합니다.
이것을 알고,당신은 적용해야 합 코드 기술 특정 지시 비순환 그래프.