2017-01-21 2 views
0

모든 작업을 가능한 가장 효율적으로 구현하면서 숙제를 통해 은행 시스템을 구축했습니다.최대 힙 유지 새 항목을 삽입하는 동안 정렬

프로그램 할 수 있습니다 내가 처음 3 것들에 대한 레드 - 블랙 트리 가기로 결정

1.add a new customer 
2.delete an existing customer 
3.find a customer 
4.print the customer with the highest balance. 
5.print all customers with a negative balance. 
6.deposit/withdraw money 

(O (로그 N)). 나는 4th와 5th에 관해서 확실하지 않다.

4 : 최대 힙을 유지하는 것에 대해 생각 했으므로 가장 부유 한 고객을 불러 오면 루트 노드 인 O (1) 만들 수 있습니다. 내 최대 힙 코드가 시도한 랜덤 배열 (목록)에서 작동합니다. 그러나이 특정 경우에, 나는 분명히 나중에 채워 져야하는 빈 배열로 시작합니다. insert 메서드를 최대 힙에 사용하면 정렬되지 않은 배열이됩니다 (). (기본적으로 나는 힙 빌딩을 건너 뜁니다.). 최대 힙 삽입 방법 :

dataArray.add(newCustomer); 
heapSize = dataArray.size(); 
int i = dataArray.size()-1; 
while(i > 1 && dataArray.get(getParentIndex(i)).getAccountBalance() < newCustomer.getAccountBalance()) 
{ 
    swap(dataArray, getParentIndex(i) , i); 
    i = getParentIndex(i); 
} 

5 : 나는 음의 균형을 가진 사람들의 연결리스트를하는 것에 대한 생각했다. 이렇게하면 인쇄 할 때 복잡성이 선형이됩니다. (RBTree는 마이너스 잔액이없는 고객이 있더라도 logN 비용이들 것입니다.) 그러나 고객을 삭제할 경우 해당 목록에서 고객을 찾아서 제거해야합니다 (RBTree 삭제 lgn + n 목록 삭제 = n * lgn)

+0

나는 균형은 시간이 지남에 따라 변경 될 수 있다고 생각. 포인트 5에 대한 귀하의 목록은 이에 따라 유지 관리되어야합니다. BTW O (lgn + n)은 O (n)가 아니라 O (n * lgn)입니다. 또한 이러한 목록을 일관되게 유지할 수 있다고 보장 할 수 있다면 포인트 4에 대한 단일 객체 (최대 값)를 유지할 수 있으므로 추가 작업 없이도 일정 시간 작업이 가능합니다. 최대 힙. –

+0

예, 죄송합니다. 예금/인출 옵션도 있습니다. 목록에 관해서는, 삽입, 삭제 및 보관 후에도이를 유지해야하며 최대 힙에 대해서도 마찬가지입니다. RBTree를 순회하는 것보다 효과적이지 않습니다. 권리? 그래서 어쩌면 나는 RBTree를 모든 것에 사용해야 만한다. 빈리스트를 가져 오는 것이 가능한가? 새로운 삽입이있을 때마다 힙을 정렬 된 상태로 유지 하는가? – BVtp

+0

힙을 잊어 버리십시오. RB 트리보다 더 많은 데이터 구조를 가질 필요가 없습니다. 올바르게 사용하십시오. 트리에서 가장 오른쪽 노드에있을 때까지 루트에서 오른쪽 하위 포인터를 내림으로써 가장 높은 균형을 찾을 수 있습니다. 그것은 가장 큰 항목입니다. 순서없는 검색을 시작하고 첫 번째 음수가 아닌 잔액을 찾을 때 중지하면 모든 음수 값을 인쇄 할 수 있습니다. – Gene

답변

0

나는 두 개의 이진 탐색 트리 (키는 고유 한 고객 ID)를 유지할 것이며, 하나는 음수 균형을, 다른 하나는 양수 균형을 유지하는 고객을위한 것입니다. 그리고 항상 가장 높은 균형을 가진 고객을 가리키는 포인터 richest.

모든 잔액이 변경 될 때 잔액의 부호가 변경되었는지 확인해야합니다. 그렇다면 한 트리에서 고객을 삭제하고 다른 트리에 추가하십시오.

그리고 현재 잔액이 잔액이 richest인지 확인하고 잔액이 더 높은 경우 현재 고객을 지정하십시오.

복잡성은 다음과 같습니다

1. insert to tree: O(log(n)) 
2. delete from tree: O(log(n)) 
3. binary search in two trees: O(log(n)) 
4. print the customer pointed by `richest`: O(1) 
5. in-order run on a binary search tree (the negative one): O(n) 
6. find costumer: O(log(n)) + possible deletions and insertions: still O(log(n)) 
+0

Nimrod는 제안에 대해 대단히 감사합니다. 내가 모은 것에서 시간을 들여 나무와 힙을 사용하는 것과 같은 복잡성을 지닌 것인가? 공간적으로 다른 트리는 O (n)을 필요로하지만 O (1)은 힙만 O (1)가 필요합니다. 지난 해 수업에서 비슷한 솔루션 (2 나무 사용)을 보았습니다. 그리고 공간에서도 충분히 효율적이지 않다는 점을 공제했습니다. :/내가 알아낼 수있는 방법이 없다면 아마 해결책을 찾을 것입니다. 그래도 힙과 함께 작동하게하십시오 ... – BVtp

+0

또한, 모든 음수 잔액을 인쇄하는 것과 관련하여 - 최악의 경우, 음수가없는 경우를 찾기 위해 O (lgn)가 필요합니다. 아마도 LinkedList의 일부 유형에 마이너스 잔액을 저장하면 도움이 될까요? 가장 좋은 경우 O (1) (비어 있음을 확인), 최악의 경우 선형 복잡성. – BVtp

+0

@BVtp 사용 된 전체 공간은 항상 고객 수입니다. 모든 고객에 대해 하나의 트리 노드를 보유합니다. 두 나무는 부정적인 균형과 긍정적 인 균형을 쉽게 분리시킵니다. 음의 균형이 없다면 그 나무는 단지 뿌리를 가질 것이고 O (1)은'부정적인 균형 없음 '을 확인하고 인쇄 할 것입니다. –

0

그냥 @Nimrod 모라 그의 솔루션의 상단에 추가가 더 나은 averageamortized 시간 복잡성을 가지고, 당신은 Fibonacci-heap 데이터 구조 (참조 https://en.wikipedia.org/wiki/Fibonacci_heaphttp://www.cs.princeton.edu/~wayne/teaching/fibonacci-heap.pdf)를 사용하고 하나를 유지할 수 있습니다 고객에 대한 fib-max-heap (A max 포인터를 가지고있는) 그리고 당신이 할 수있는 모든 작업은 :

1. insert (lazily) a customer to the heap: O(1) 
2. delete any customer (or the customer with maximum balance) 
    from heap: O(log(n)) amortized 
3. search a customer in heap: O(log(n)) 
4. print the customer pointed by `max` pointer: O(1) 
5. in-order run on the heap and print only the -ve balances: O(n) 
6. deposit/withdraw money: O(1) amortized