2008-09-16 6 views
3

나는 20s 어딘가에 깊이가있는 나무 개체를 가지고 있습니다. 이 트리의 각 노드는 트리의 루트에 액세스해야합니다.지구본을 없애고 싶습니까?

솔루션의 몇 가지 : 각 노드가 직접 루트에 대한 참조를 저장할 수 있습니다

  1. (폐기물 메모리) 내가 런타임에 뿌리를 계산할 수
    • "올라가고"에 의해 (폐기물주기)
나는 정적 필드를 사용할 수 있습니다 (그러나 이것은 전역 금액)

누구나 (어떤 변형에서든) 글로벌을 사용하지 않지만 메모리 나 사이클 모두에서 # 1 또는 # 2보다 효율적인 디자인을 제공 할 수 있습니까?

편집 : 트리 세트가 있기 때문에 나무 사이를 구별하기가 쉽지 않으므로 정적으로 저장할 수 없습니다. (thanks maccullt)

+0

나무의 숲이 있는지 여부는 분명하지 않지만 몇 가지 뿌리가 필요하거나 루트가 하나있는 경우에는 분명합니다. 숲의 경우 통계학이 문제를 해결하는 방법을 알지 못합니다. 나무 당 하나의 뿌리가 필요하지 않으며 각 나무는 뿌리를 참조합니다 (해결책 1). – maccullt

답변

6

루트를 필요한 노드의 기능에 매개 변수로 전달하십시오.

편집 : 옵션은 다음 정말 :

  1. 스토어
  2. 글로벌
  3. 의 모든
  4. 스토어 루트 참조에서 루트 참조를 보관하지 마십시오 노드의 루트 참조
  5. 스택에 루트 참조를 저장하십시오 (내 제안, 방문자 패턴 또는 재귀 중 하나)

나는이 모든 th e 옵션을 사용할 수 없습니다.

+0

Ala 방문자 패턴 깔끔합니다. 나는 그걸 생각하지 않았다. –

+0

뭔가가 변할 때 매우 고통 스럽습니다. 특히 호출 스택이 깊어 질수록 더욱 그렇습니다. –

+0

나는 그것을 재귀 적으로 해석하지 않았다. 트리를 가로 질러 각 노드에서 실행되는 코드 조각을 가질 수 있습니다. 이 코드는 루트에 대한 참조를 갖습니다. –

3

왜 전역을 제거해야합니까? 나는 전역의 오명을 완전히 이해하지 못한다는 것을 이해하지만 때로는 모든 요소를 ​​갖춘 글로벌 데이터 구조를 갖는 것이 가장 빠른 해결책입니다.

성능을 위해 코드 명료성과 향후 문제를 줄이십시오. 그것은 '아직 최적화하지 마십시오'라는 의미입니다. 최적화 단계에 있기 때문에 때때로 가독성과 성능에 유리한 프로그래밍 기법을 제거해야합니다. 비트 해킹은 읽을 수 없지만 속도가 빠릅니다.

보유하고있는 나무 개체 수는 확실하지 않지만 개인적으로 옵션 1을 사용합니다. 당신이 수천 가지의 나무를 다루지 않는다면, 포인터는 정말로 그다지 많은 문자열에 미치지 못할 것입니다. 메모리가 정말로 중요한 문제라면, 두 가지 방법을 시도해보십시오 (구현하기가 상당히 간단 해 보입니다). 그리고 프로파일 러를 통해 실행하십시오. 또는 우수한 Process Explorer을 사용하십시오.

편집 : 내가 작업하고있는 앱 중 하나에는 약 55K 노드가 포함 된 노드 트리가 있습니다. 우리는 트리 구조를 만들지 만 O (1) 룩업을위한 배열도 유지합니다. 재귀적인 FindNodeByID 메소드를 사용할 때 우리가 얻었던 O (m * n)보다 훨씬 낫습니다.

+0

20000 노드 이상입니다. 그래서 그 포인터 80k. –

+0

80k ... ?? 당신은 meg의 10 분의 1 미만을 걱정하고 있습니다 ... ?? 존재하지 않는 문제에 대해 강조하고있는 것처럼 들립니다. –

+0

강조하지 않고 호기심을 자극합니다. 나는 그것이 깔끔한 질문이라고 생각했다. –

1

포인트 # 1은 조기 메모리 최적화입니다. # 2는 조기 성능 최적화입니다. 메모리 또는 CPU 병목 현상이 문제를 일으키는 지 확인하기 위해 앱을 프로파일 링 했습니까?그렇지 않은 경우 사용자에게 도움이되지 않는 "최적화"를 위해 유지 관리가 용이 ​​한 디자인을 왜 희생해야합니까?

# 2와 (과) 같이하는 것이 좋습니다. 대신 계산할 수있는 것을 저장할 때마다 캐싱이 수행됩니다. 캐싱이 좋은 생각인데 몇 번이고, 또한 유지 보수의 골칫거리입니다. (예를 들어 부모를 변경하여 한 트리에서 다른 트리로 노드를 이동하지만 루트 필드도 업데이트하는 것을 잊어 버린 경우 어떻게해야합니까?) 할 필요가 없다면 캐시하지 마십시오.

0

TreeView에서 클래스를 파생시킨 다음 단일 정적 속성을 추가 할 수 있습니다. 그렇게하면 클래스의 단일 인스턴스를 참조하는 전역 필드를 효과적으로 추가 할 수 있지만 해당 클래스의 범위가 네임 스페이스라는 이점이 있습니다.

0

내부 클래스에 대한 혐오감을 무시하고 Tree 클래스를 정의하고 노드를 내부 클래스로 정의 할 수있었습니다. 각 노드는 루트를 포함하여 트리의 상태에 액세스 할 수 있습니다.

Java가 노드를 부모와 연관시키는 방식에 따라 # 1과 같을 수도 있습니다. (나는 잘 모르겠다. 프로필을 작성해야한다.)

+0

# 1과 거의 같을 것입니다. 구현할 수있는 다른 방법은 없습니다. – Niall

2

일반적으로 매개 변수로 루트를 전달하는 것이 가장 좋습니다. 어떤 종류의 반복자를 사용하여 트리를 탐색하는 경우, 대신 루트에 대한 참조를 저장하는 것이 좋습니다.

관련 문제