最小堆是否排序为"默认"

时间:2015-08-11 19:19:05

标签: c# algorithm sorting heap min-heap

我刚拿起"算法简介",我开始在c#中实现堆和堆算法。

实现一个从双精度数组构造最小/最大堆的函数,我注意到构造的堆有一些有趣的属性。

构建的最小堆可以从左到右,从上到下(从根到叶,按级别)读取,并且它将被排序。

这是minheap的属性,还是我无法获得此属性不适用的案例。最大堆不会这样工作,至少我得到的是这里。

输出:

2345 7 34 6 3 5 4 5 1 2 3 2 1 3 1 3 2 1(maxheap)

1 1 1 1 2 2 2 3 3 3 3 4 5 5 6 7 34 2345(minheap)

感谢您提前做出任何回复!

2 个答案:

答案 0 :(得分:4)

堆只有父节点和它们各自的子节点之间的关系。 同一级别的节点之间没有关系。

CREATE TYPE param_tbl_type IS TABLE OF VARCHAR2(255);

CREATE OR REPLACE FUNCTION 
    (p_param_names param_tbl_type,
     p_param_values param_tbl_type)
RETURN VARCHAR2
IS
    l_dyn_func_str VARCHAR2(4000);
    l_ret_val VARCHAR2(4000);
    vCursor integer;
    fdbk PLS_INTEGER;
BEGIN

   -- make sure you have equal number of params and currespondin values. 
   -- Index much match too. i.e. if p_param_names(0) is 'p_currency' then p_param_value(0) must be 'USD' (value of currency)
   IF p_param_names.COUNT <> p_param_values.COUNT THEN
      raise_application_error(-2000,'Incorrect number of arguments');
   END IF;

   -- use this variable to generate anonymous block code
   l_dyn_fun_str:='BEGIN :retval :=  function_tobe_called (';

   -- loop through each parameter and add to the parameter list 
   FOR i in 1..p_param_names.COUNT LOOP
      IF i=0 THEN
        l_dyn_fun_str:=l_dyn_fun_str||':'||l_param_name(i);
      ELSE
        l_dyn_fun_str:=l_dyn_fun_str||','||':'||l_param_name(i);
      END IF;
   END LOOP;

   l_dyn_fun_str:=l_dyn_fun_str||'); END;'

   -- open cursor and associate with function call string (l_dyn_fun_str)
   vCursor:=DBMS_SQL.OPEN_CURSOR;
   DBMS_SQL.PARSE(vCursor,l_dyn_fun_str);

   -- loop through parameter values and associate them with bind variables
   DBMS_SQL.BIND_VARIABLE(vCursor,':retval',l_ret_val);
   FOR j in 1..p_param_values.COUNT LOOP
      DBMS_SQL.BIND_VARIABLE(vCursor, ':'||l_param_names(j), l_param_values(j));
   END LOOP;
   -- execute function 
   fdbk := DBMS_SQL.EXECUTE (vCursor);

   -- get output of function 
   DBMS_SQL.VARIABLE_VALUE (vCursor, 'retval', l_ret_val);
   RETURN l_ret_val;


END;

因此,当从上到下,从左到右行进时,Min Heap不需要进行排序。在你的情况下,这只是巧合。
例如:请考虑以下顺序: For Min Heaps: Value of Parent node <= Value of its child nodes For Max Heaps: Value of Parent node >= Value of its child nodes Heap for above sequence
这些是MinHeapify订单,但按排序顺序显然 请访问此Interactive Heap Linkthis link ,以正确显示堆的构建方式。

答案 1 :(得分:0)

为了使堆的实现更加健壮,人们通常会调用您可以对节点执行的两个操作:siftpercolate

sift通过使用您找到的两个儿子中最好的一个切换节点,使节点尽可能地降低到树上。

可能会实施sift程序

 public void sift (int i)
    {
        while (i != 0)
        {
            if (compare(heapData[i], parentValue(i)))
            {
                switchValuesAtIndexes(parentIndex(i), i);
                i = parentIndex(i);
            }
            else
                break;
        }
    }

percolate通过使用父节点切换节点,使节点尽可能多地在树上运行。

public void percolate (int i)
    {
        while (true)
        {
            if (indexExists(leftIndex(i)) && (!indexExists(rightIndex(i)) && compare(leftValue(i), heapData[i]) || indexExists(rightIndex(i)) && compare(leftValue(i), rightValue(i)) && compare (leftValue (i), heapData[i])))
            {
                switchValuesAtIndexes(leftIndex(i), i);
                i = leftIndex(i);
            }
            else
                if (indexExists(rightIndex(i)) && (compare (rightValue(i), leftValue(i)) && compare (rightValue(i), heapData[i])))
                {
                    switchValuesAtIndexes(rightIndex(i), i);
                    i = rightIndex(i);
                }
            else
                break;
        }
    }

要构建堆,您需要将siftpercolate(或两者)应用于数组的每个元素

要对您构建的堆进行排序,您必须打印第一个元素(这是所有堆中最好的,与您定义的比较器,min,max等相符) 然后你必须用最后一个“覆盖”第一个元素并删除最后一个元素,然后你必须在第一个元素上应用sift以使它在堆中的正确位置。然后重复,直到堆中没有元素