Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 插入新项目时维护最大堆排序_Arrays_Algorithm_Sorting_Math_Tree - Fatal编程技术网

Arrays 插入新项目时维护最大堆排序

Arrays 插入新项目时维护最大堆排序,arrays,algorithm,sorting,math,tree,Arrays,Algorithm,Sorting,Math,Tree,我的家庭作业是建立一个银行系统,同时以最有效的方式执行所有任务 该计划可以: 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(lo

我的家庭作业是建立一个银行系统,同时以最有效的方式执行所有任务

该计划可以:

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(log-n))。 不过,我不确定第四次和第五次

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);
}
dataArray.add(新客户);
heapSize=dataArray.size();
int i=dataArray.size()-1;
而(i>1&&dataArray.get(getParentIndex(i)).getAccountBalance()
他说:我想建立一个负余额的链接列表。 这样,打印时的复杂性将是线性的。(即使没有负余额的客户,RBTree也会花费logN)。
但是,如果我删除一个客户,我必须搜索该列表中的(O(n))客户以删除他,然后删除功能将是(RBTree delete lgn+n list delete=n*lgn)

我将维护两个二进制搜索树(键将是唯一的客户ID),一个用于负余额客户,另一个用于正余额客户。还有一个指针
最富有的
,它总是指向余额最高的客户

在每次余额变化中,你应该检查余额的符号是否发生变化。如果是这样,请从一个树中删除客户并将其添加到另一个树中

并将当前余额与
最富有的
余额进行对比,如果当前客户的余额较高,则分配给当前客户

复杂性将是:

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))

只需在@Nimrod Morag的解决方案的基础上添加,为了获得更好的
平均值
摊销
时间复杂性,您可以使用
Fibonacci堆
数据结构(ref和),并为客户保留一个
fib max堆
(具有
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

我想随着时间的推移,平衡会发生变化。您的第5点列表必须相应保留。顺便说一句,O(lgn+n)是O(n),而不是O(n*lgn)。此外,如果您能够保证这样一个列表可以一致地维护,这意味着您还可以为第4点维护一个对象(这只是一个最大值),使其成为一个固定时间操作,而不需要额外的最大堆。是的,对不起,还有存款/取款选项。关于列表,维护它(在插入、删除和存放之后,对于max heap也是如此)相对于只遍历RBTree是无效的。正确的?所以也许我应该用RBTree做所有的事情。。是否有可能获取一个空列表,并在每次新插入时保持堆的排序?忘记堆。没有必要拥有比RB树更多的数据结构。只要正确使用它。您可以通过从根目录中递减右子指针,直到到达树中最右边的节点,来找到最高的平衡点。那是最大的入口。您可以通过启动顺序搜索并在找到第一个非负余额时停止来打印所有负值。@Gene首先,感谢您的建议。第二,这意味着如果我没有弄错的话,打印最高余额将需要O(lgn)而不是O(1),而O(1)可以通过使用堆来实现。用堆实现它是不可能的吗?另外,关于打印所有负余额,在最坏的情况下,需要O(lgn)才能发现在没有负余额的情况下没有负余额。也许将负余额存储在某种类型的LinkedList中会有所帮助?O(1)在最好的情况下(检查它是否为空),在最坏的情况下线性复杂度。Nimrod非常感谢您的建议。从我收集的信息来看,时间方面的复杂性与使用树和堆是一样的,对吗?但是在空间方面,另一棵树需要O(n),而堆只需要O(1)。我在去年的课程中看到了一个类似的解决方案(使用2棵树),他们也因为在空间上不够高效而扣了分我可能会选择你的解决方案,如果我没有办法让它与堆一起工作的话……另外,关于打印所有负余额,在最坏的情况下,只需要O(lgn)就可以在没有负余额的情况下发现没有负余额。也许将负余额存储在某种类型的LinkedList中会有所帮助?O(1)在最佳情况下(检查是否为空),在最坏情况下为线性复杂度。@BVtp使用的总空间始终是客户数,我们为每个客户保留一个树节点。这两棵树更容易区分负平衡和正平衡。如果没有负余额,那么该树将只有一个根,并且需要O(1)来检查并打印
无负余额。