【问题标题】:Implement Heap using a Binary Tree使用二叉树实现堆
【发布时间】:2013-08-16 23:08:07
【问题描述】:

这个问题以前在 Stack Exchange 中被问过,但没有得到回答。

链接到之前提出的问题: Binary Heap Implemented via a Binary Tree Structure

如何在二叉树中实现堆。要实现堆,重要的是要知道最后填充的节点和第一个未占用的节点。这可以在树的级别排序中完成,但是时间复杂度将是 O(n),只是为了找到第一个未占用的节点。那么,如何在 O(logn) 的二叉树中实现堆?

谢谢 谢卡尔

【问题讨论】:

  • 已经被回答了。给定的答案有什么问题?
  • 答案没有提到如何找到第一个未被占用的叶子,它只是提到我们需要在第一个未被占用的叶子中添加新元素。据我了解,您需要对树进行级别排序以找到下一个未占用的叶子,这将花费 O(n)
  • 据我所知,您基本上是通过存储来跟踪它。
  • 是的,我尝试编写它。问题是,如果您不保留指向父节点的指针,那么跟踪下一个未占用的叶子就会出现问题。我们可以维护一个变量来存储这些信息,但是计算它需要 O(n)。假设我们在第 4 层(根为 0),并且在第 4 层从左开始有 4 个元素。现在,要获取下一个未占用的叶子,我们需要获取 2 级的兄弟,即转到 1 级的父级。这需要 O(n),因为在某种程度上我们是在进行级别排序。

标签: java heap binary-tree


【解决方案1】:

要实现具有 O(log n) 时间复杂度的二叉树堆,您需要将节点总数存储为实例变量。

假设我们有一个总共 10 个节点的堆。

如果我们要添加一个节点...

我们将节点总数加一。现在我们总共有 11 个节点。我们将新的节点总数(11)转换为其二进制表示:1011。

使用总节点 (1011) 的二进制表示,我们去掉了第一个数字。之后,我们使用 011 在树中导航到下一个要插入节点的位置。0 表示向左,1 表示向右。因此,使用 011,我们将向左、向右、向右……这会将我们带到下一个要插入的位置。

我们每层检查一个节点,使得时间复杂度 O(log n)

【讨论】:

  • 这很整洁。如果您无法获得数字的二进制表示,您仍然可以确定(从根开始)是向左还是向右。你知道这棵树有多少层: level = floor( log(11)/log(2) ) = 3;您知道此级别中最左侧元素的偏移量:offset = 11 - ( 2^level - 1 );在这个级别最多可以有多少个节点:max = 2^3 = 8;如果偏移量小于最大值的一半,那么您将在左子树中,如果大于一半,则向右走。当你往下走时,你会更新关卡和偏移量并完成!
  • @Bartel +1 这也很简洁!你们有没有从cpp.edu/~ftang/courses/CS241/notes/… 学到这个?只是好奇
  • @Bartel 另一种快速方法是,步骤 1:如果索引是奇数 - 它是正确的孩子。本例11,右子。 Step2:找到父索引= floor(index/2)。本例 floor(11/2) = 5。 第 3 步:重复直到得到 1,即树的根。这种情况下 5 - 右孩子,地板(5/2)= 2,2 - 左孩子,2/2 = 1 - 根。所以我们得到了root,left,right,right。 1......2......5.......11
【解决方案2】:

你不会实现堆IN二叉树,因为堆是A二叉树。堆维护以下 order 属性 - 给定节点 V,其父节点大于或等于 V。堆也是完整的binary tree。我在 uni 上过 ADS 课程,所以稍后我将在答案中为您提供我在 Java 中的堆实现。仅列出您获得的主要方法复杂性:

  • 大小() O(1)
  • isEmpty() O(1)
  • insert() O(logn)
  • removeMin() O(logn)
  • min() O(1)

这是我的Heap.java 文件:

public class Heap<E extends Comparable<E>> {

    private Object S[];
    private int last;
    private int capacity;

    public Heap() {
        S = new Object[11];
        last = 0;
        capacity = 7;
    }

    public Heap(int cap) {
        S = new Object[cap + 1];
        last = 0;
        capacity = cap;
    }

    public int size() {
        return last;
    }

    //
    // returns the number of elements in the heap
    //

    public boolean isEmpty() {
        return size() == 0;
    }

    //
    // is the heap empty?
    //

    public E min() throws HeapException {
        if (isEmpty())
            throw new HeapException("The heap is empty.");
        else
            return (E) S[1];
    }

    //
    // returns element with smallest key, without removal
    //

    private int compare(Object x, Object y) {
        return ((E) x).compareTo((E) y);
    }

    public void insert(E e) throws HeapException {
        if (size() == capacity)
            throw new HeapException("Heap overflow.");
        else{
            last++;
            S[last] = e;
            upHeapBubble();
        }       
    }

    // inserts e into the heap
    // throws exception if heap overflow
    //

    public E removeMin() throws HeapException {
        if (isEmpty())
            throw new HeapException("Heap is empty.");
        else {
            E min = min();
            S[1] = S[last];
            last--;
            downHeapBubble();
            return min;
        }
    }

    //
    // removes and returns smallest element of the heap
    // throws exception is heap is empty
    //

    /**
     * downHeapBubble() method is used after the removeMin() method to reorder the elements
     * in order to preserve the Heap properties
     */
    private void downHeapBubble(){
        int index = 1;
        while (true){
            int child = index*2;
            if (child > size())
                break;
            if (child + 1 <= size()){
                //if there are two children -> take the smalles or
                //if they are equal take the left one
                child = findMin(child, child + 1);
            }
            if (compare(S[index],S[child]) <= 0 )
                break;
            swap(index,child);
            index = child;
        }
    }

    /**
     * upHeapBubble() method is used after the insert(E e) method to reorder the elements
     * in order to preserve the Heap properties 
     */
    private void upHeapBubble(){
        int index = size();
        while (index > 1){
            int parent = index / 2;
            if (compare(S[index], S[parent]) >= 0)
                //break if the parent is greater or equal to the current element
                break;
            swap(index,parent);
            index = parent;
        }       
    }

    /**
     * Swaps two integers i and j
     * @param i
     * @param j
     */
    private void swap(int i, int j) {
        Object temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }

    /**
     * the method is used in the downHeapBubble() method
     * @param leftChild
     * @param rightChild
     * @return min of left and right child, if they are equal return the left
     */
    private int findMin(int leftChild, int rightChild) {
        if (compare(S[leftChild], S[rightChild]) <= 0)
            return leftChild;
        else
            return rightChild;
    }

    public String toString() {
        String s = "[";
        for (int i = 1; i <= size(); i++) {
            s += S[i];
            if (i != last)
                s += ",";
        }
        return s + "]";
    }
    //
    // outputs the entries in S in the order S[1] to S[last]
    // in same style as used in ArrayQueue
    //

}

HeapException.java:

public class HeapException extends RuntimeException {
    public HeapException(){};
    public HeapException(String msg){super(msg);}
}

为您提供 O(logn) 性能的有趣部分是 downHeapBubble()upHeapBubble() 方法。我很快就会对它们进行很好的解释。

upHeapBubble() 在向堆中插入新节点时使用。因此,当您插入时,您插入到最后一个位置,然后您需要像这样调用upHeapBubble()

last++;
S[last] = e;
upHeapBubble();

然后将最后一个元素与它的父元素进行比较,如果父元素更大 - 交换:这是最大 logn 次,其中 n 是节点数。所以这里是登录性能。

对于删除部分 - 您只能删除 min - 最高节点。所以当你删除它时——你必须将它与最后一个节点交换——但是你必须维护堆属性并且你必须做一个downHeapBubble()。如果节点大于它的子节点,则与最小的节点交换,依此类推,直到您没有任何子节点或您没有更小的子节点。这可以在最大登录时间完成,因此这里是登录性能。您可以通过查看二叉树图片here

来解释为什么此操作可以完成最大登录次数

【讨论】:

  • Anton,我知道堆使用数组的实现。我对树的实现很感兴趣。 bdw 感谢您的回答。
  • 我会为@Anton Belev 辩护。 S 就是我所说的基于数组的二叉树实现。每个节点(数组元素)都有一个左右子节点,它们可以通过公式而不是指针找到,但我认为这并不能定义二叉树是什么。即使我对另一种情况提出了建议,我认为 OP 应该更明确。
  • 为什么默认预留11个slot的数组?
  • 当你不想使用内存中的连续空间来存储优先级堆时,则使用基于指针的实现
  • 投反对票,因为它是基于数组的实现,而不是基于问题中所需的二叉树
【解决方案3】:

使用树实现堆

我正在回答我自己的问题,需要 O(log n),但限制是保留指向父级的指针。如果我们不保留指向父级的指针,我们需要大约 O(n)。我发布了这个问题以获得 O(log n) 的解决方案

以下是计算下一个未占用叶子的步骤(我们有一个指向父节点的指针):

x = last inserted node. We save this after every insertion.
y = tmp node
z = next unoccupied node (next insertion)
   if x is left child
      z = x -> parent -> rightchild (problem solved.. that was easy)
   else if x is right child
      go to x's parent, until parent becomes left child. Let this node be y
      (subtree rooted at y's sibling will contain the next unoccupied node)
      z = y -> parent -> right -> go left until null

这是 O(log n),但需要一个指向父级的指针。

O(n) 解决方案非常简单,只需对树进行级别排序,我们就可以得到下一个未占用节点的位置。

我的问题是:如何在不使用父指针的情况下定位 O(log n) 中的下一个未占用节点。

谢谢。

【讨论】:

  • 我很抱歉格式化。我做了 cntrl k 来格式化它,它变成了这样。
【解决方案4】:

假设您想使用 linked 二叉树,没有指向父节点的指针,那么我能想到的唯一解决方案是在每个节点中保留一个子节点数计数器。

availableLeaf(node) {
    if( node.left is Empty || node.right is Empty )
        return node ;
    else
       if( node.left.count < node.right.count )
           return availableLeaf(node.left)
       else
           return availableLeaf(node.right)
}

这种策略还可以平衡每个子树每一侧的节点数量,这是有益的(尽管非常轻微)。

这是 O(log n)。跟踪插入计数需要一直到屋顶,但这不会改变此操作的 O(lon n) 性质。与删除类似。

其他操作都是常规操作,并保留其性能特征。

您需要详细信息还是更愿意自己解决?

如果您想使用链接二叉树,除了左右指针之外没有其他信息,那么我建议您启动至少 100,000 点的赏金。我并不是说这是不可能的(因为我没有数学来证明它),而是我说这是几十年来都没有发现的(我确实知道)。

【讨论】:

    【解决方案5】:

    我的堆实现

    public class Heap <T extends Comparable<T>> {
        private T[] arr;
        private int size;
    
        public Heap(T[] baseArr) {
            this.arr = baseArr;
            size = arr.length - 1;
        }
    
        public void minHeapify(int i, int n) {
            int l = 2 * i + 1;
            int r = 2 * i + 2;
    
            int smallest = i;
            if (l <= n && arr[l].compareTo(arr[smallest]) < 0) {
                smallest = l;
            }
            if (r <= n && arr[r].compareTo(arr[smallest]) < 0) {
                smallest = r;
            }
    
            if (smallest != i) {
                T temp = arr[i];
                arr[i] = arr[smallest];
                arr[smallest] = temp;
                minHeapify(smallest, n);
            }
        }
    
        public void buildMinHeap() {
            for (int i = size / 2; i >= 0; i--) {
                minHeapify(i, size);
            }
        }
    
        public void heapSortAscending() {
            buildMinHeap();
            int n = size;
            for (int i = n; i >= 1; i--) {
                T temp = arr[0];
                arr[0] = arr[i];
                arr[i] = temp;
                n--;
                minHeapify(0, n);
            }
        }
    }
    

    【讨论】:

      【解决方案6】:
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * @author Harish R
       */
      public class HeapPractise<T extends Comparable<T>> {
      
          private List<T> heapList;
      
          public List<T> getHeapList() {
              return heapList;
          }
      
          public void setHeapList(List<T> heapList) {
              this.heapList = heapList;
          }
      
          private int heapSize;
      
          public HeapPractise() {
              this.heapList = new ArrayList<>();
              this.heapSize = heapList.size();
          }
      
          public void insert(T item) {
              if (heapList.size() == 0) {
                  heapList.add(item);
              } else {
                  siftUp(item);
              }
      
          }
      
          private void siftUp(T item) {
              heapList.add(item);
              heapSize = heapList.size();
              int currentIndex = heapSize - 1;
              while (currentIndex > 0) {
                  int parentIndex = (int) Math.floor((currentIndex - 1) / 2);
                  T parentItem = heapList.get(parentIndex);
                  if (parentItem != null) {
                      if (item.compareTo(parentItem) > 0) {
                          heapList.set(parentIndex, item);
                          heapList.set(currentIndex, parentItem);
                          currentIndex = parentIndex;
                          continue;
                      }
                  }
                  break;
              }
          }
      
          public T delete() {
              if (heapList.size() == 0) {
                  return null;
              }
              if (heapList.size() == 1) {
                  T item = heapList.get(0);
                  heapList.remove(0);
                  return item;
              }
              return siftDown();
          }
      
          private T siftDown() {
              T item = heapList.get(0);
              T lastItem = heapList.get(heapList.size() - 1);
              heapList.remove(heapList.size() - 1);
              heapList.set(0, lastItem);
              heapSize = heapList.size();
              int currentIndex = 0;
              while (currentIndex < heapSize) {
                  int leftIndex = (2 * currentIndex) + 1;
                  int rightIndex = (2 * currentIndex) + 2;
                  T leftItem = null;
                  T rightItem = null;
                  int currentLargestItemIndex = -1;
                  if (leftIndex <= heapSize - 1) {
                      leftItem = heapList.get(leftIndex);
                  }
                  if (rightIndex <= heapSize - 1) {
                      rightItem = heapList.get(rightIndex);
                  }
                  T currentLargestItem = null;
                  if (leftItem != null && rightItem != null) {
                      if (leftItem.compareTo(rightItem) >= 0) {
                          currentLargestItem = leftItem;
                          currentLargestItemIndex = leftIndex;
                      } else {
                          currentLargestItem = rightItem;
                          currentLargestItemIndex = rightIndex;
                      }
                  } else if (leftItem != null && rightItem == null) {
                      currentLargestItem = leftItem;
                      currentLargestItemIndex = leftIndex;
                  }
                  if (currentLargestItem != null) {
                      if (lastItem.compareTo(currentLargestItem) >= 0) {
                          break;
                      } else {
                          heapList.set(currentLargestItemIndex, lastItem);
                          heapList.set(currentIndex, currentLargestItem);
                          currentIndex = currentLargestItemIndex;
                          continue;
                      }
                  } else {
                      break;
                  }
              }
              return item;
      
          }
      
          public static void main(String[] args) {
              HeapPractise<Integer> heap = new HeapPractise<>();
      
              for (int i = 0; i < 32; i++) {
                  heap.insert(i);
              }
              System.out.println(heap.getHeapList());
              List<Node<Integer>> nodeArray = new ArrayList<>(heap.getHeapList()
                      .size());
              for (int i = 0; i < heap.getHeapList().size(); i++) {
                  Integer heapElement = heap.getHeapList().get(i);
                  Node<Integer> node = new Node<Integer>(heapElement);
                  nodeArray.add(node);
              }
              for (int i = 0; i < nodeArray.size(); i++) {
                  int leftNodeIndex = (2 * i) + 1;
                  int rightNodeIndex = (2 * i) + 2;
                  Node<Integer> node = nodeArray.get(i);
                  if (leftNodeIndex <= heap.getHeapList().size() - 1) {
                      Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
                      node.left = leftNode;
                  }
                  if (rightNodeIndex <= heap.getHeapList().size() - 1) {
                      Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
                      node.right = rightNode;
                  }
              }
              BTreePrinter.printNode(nodeArray.get(0));
              System.out.println(heap.delete());
              nodeArray = new ArrayList<>(heap.getHeapList().size());
              for (int i = 0; i < heap.getHeapList().size(); i++) {
                  Integer heapElement = heap.getHeapList().get(i);
                  Node<Integer> node = new Node<Integer>(heapElement);
                  nodeArray.add(node);
              }
              for (int i = 0; i < nodeArray.size(); i++) {
                  int leftNodeIndex = (2 * i) + 1;
                  int rightNodeIndex = (2 * i) + 2;
                  Node<Integer> node = nodeArray.get(i);
                  if (leftNodeIndex <= heap.getHeapList().size() - 1) {
                      Node<Integer> leftNode = nodeArray.get(leftNodeIndex);
                      node.left = leftNode;
                  }
                  if (rightNodeIndex <= heap.getHeapList().size() - 1) {
                      Node<Integer> rightNode = nodeArray.get(rightNodeIndex);
                      node.right = rightNode;
                  }
              }
              BTreePrinter.printNode(nodeArray.get(0));
          }
      }
      
      public class Node<T extends Comparable<?>> {
          Node<T> left, right;
          T data;
      
          public Node(T data) {
              this.data = data;
          }
      }
      
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.List;
      
      class BTreePrinter {
      
          public static <T extends Comparable<?>> void printNode(Node<T> root) {
              int maxLevel = BTreePrinter.maxLevel(root);
      
              printNodeInternal(Collections.singletonList(root), 1, maxLevel);
          }
      
          private static <T extends Comparable<?>> void printNodeInternal(
                  List<Node<T>> nodes, int level, int maxLevel) {
              if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
                  return;
      
              int floor = maxLevel - level;
              int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
              int firstSpaces = (int) Math.pow(2, (floor)) - 1;
              int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
      
              BTreePrinter.printWhitespaces(firstSpaces);
      
              List<Node<T>> newNodes = new ArrayList<Node<T>>();
              for (Node<T> node : nodes) {
                  if (node != null) {
                      String nodeData = String.valueOf(node.data);
                      if (nodeData != null) {
                          if (nodeData.length() == 1) {
                              nodeData = "0" + nodeData;
                          }
                      }
                      System.out.print(nodeData);
                      newNodes.add(node.left);
                      newNodes.add(node.right);
                  } else {
                      newNodes.add(null);
                      newNodes.add(null);
                      System.out.print("  ");
                  }
      
                  BTreePrinter.printWhitespaces(betweenSpaces);
              }
              System.out.println("");
      
              for (int i = 1; i <= endgeLines; i++) {
                  for (int j = 0; j < nodes.size(); j++) {
                      BTreePrinter.printWhitespaces(firstSpaces - i);
                      if (nodes.get(j) == null) {
                          BTreePrinter.printWhitespaces(endgeLines + endgeLines + i
                                  + 1);
                          continue;
                      }
      
                      if (nodes.get(j).left != null)
                          System.out.print("//");
                      else
                          BTreePrinter.printWhitespaces(1);
      
                      BTreePrinter.printWhitespaces(i + i - 1);
      
                      if (nodes.get(j).right != null)
                          System.out.print("\\\\");
                      else
                          BTreePrinter.printWhitespaces(1);
      
                      BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
                  }
      
                  System.out.println("");
              }
      
              printNodeInternal(newNodes, level + 1, maxLevel);
          }
      
          private static void printWhitespaces(int count) {
              for (int i = 0; i < 2 * count; i++)
                  System.out.print(" ");
          }
      
          private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
              if (node == null)
                  return 0;
      
              return Math.max(BTreePrinter.maxLevel(node.left),
                      BTreePrinter.maxLevel(node.right)) + 1;
          }
      
          private static <T> boolean isAllElementsNull(List<T> list) {
              for (Object object : list) {
                  if (object != null)
                      return false;
              }
      
              return true;
          }
      
      }
      

      请注意,BTreePrinter 是我很久以前在 Stackoverflow 中使用的代码,我修改为使用 2 位数字。如果我们移动到 3 位数字,它将被破坏,它只是为了简单理解堆结构的方式看起来。对于 3 位数字的解决方法是将所有内容保持为 3 的倍数。还要感谢 Sesh Venugopal 在 Youtube 上关于堆数据结构的精彩教程

      【讨论】:

        【解决方案7】:

        二叉树可以用数组表示:

        import java.util.Arrays;
        
        public class MyHeap {
            private Object[] heap;
            private int capacity;
            private int size;
        
            public MyHeap() {
                capacity = 8;
                heap = new Object[capacity];
                size = 0;
            }
        
            private void increaseCapacity() {
                capacity *= 2;
                heap = Arrays.copyOf(heap, capacity);
            }
        
            public int getSize() {
                return size;
            }
        
            public boolean isEmpty() {
                return size == 0;
            }
        
            public Object top() {
                return size > 0 ? heap[0] : null;
            }
        
            @SuppressWarnings("unchecked")
            public Object remove() {
                if (size == 0) {
                    return null;
                }
                size--;
                Object res = heap[0];
                Object te = heap[size];
                int curr = 0, son = 1;
                while (son < size) {
                    if (son + 1 < size
                            && ((Comparable<Object>) heap[son + 1])
                                    .compareTo(heap[son]) < 0) {
                        son++;
                    }
                    if (((Comparable<Object>) te).compareTo(heap[son]) <= 0) {
                        break;
                    }
                    heap[curr] = heap[son];
                    curr = son;
                    son = 2 * curr + 1;
                }
                heap[curr] = te;
                return res;
            }
        
            @SuppressWarnings("unchecked")
            public void insert(Object e) {
                if (size == capacity) { // auto scaling
                    increaseCapacity();
                }
                int curr = size;
                int parent;
                heap[size] = e;
                size++;
                while (curr > 0) {
                    parent = (curr - 1) / 2;
                    if (((Comparable<Object>) heap[parent]).compareTo(e) <= 0) {
                        break;
                    }
                    heap[curr] = heap[parent];
                    curr = parent;
                }
                heap[curr] = e;
            }
        }
        

        用法:

            MyHeap heap = new MyHeap(); // it is a min heap
            heap.insert(18);
            heap.insert(26);
            heap.insert(35);
            System.out.println("size is " + heap.getSize() + ", top is " + heap.top());
            heap.insert(36);
            heap.insert(30);
            heap.insert(10);
            while(!heap.isEmpty()) {
                System.out.println(heap.remove());
            }
        

        【讨论】:

          【解决方案8】:

          给你 - 使用二叉树实现堆

          public class PriorityQ<K extends Comparable<K>> {
          private class TreeNode<T extends Comparable<T>> {
              T val;
              TreeNode<T> left, right, parent;
              public String toString() {
                  return this.val.toString();
              }
              TreeNode(T v) {
                  this.val = v;
                  left = null;
                  right = null;
              }
              public TreeNode<T> insert(T val, int position) {
                  TreeNode<T> parent = findNode(position/2);
                  TreeNode<T> node = new TreeNode<T>(val);
                  if(position % 2 == 0) {
                      parent.left = node;
                  } else {
                      parent.right = node;
                  }
                  node.parent = parent;
                  heapify(node);
                  return node;
              }
              private void heapify(TreeNode<T> node) {
                  while(node.parent != null && (node.parent.val.compareTo(node.val) < 0)) {
                      T temp = node.val;
                      node.val = node.parent.val;
                      node.parent.val = temp; 
                      node = node.parent;
                  }
              }       
              private TreeNode<T> findNode(int pos) {
                  TreeNode<T> node = this;
                  int reversed = 1;
                  while(pos > 0) {
                      reversed <<= 1;
                      reversed |= (pos&1);                
                      pos >>= 1;
                  }
                  reversed >>= 1;
          
                  while(reversed > 1) {
                      if((reversed & 1) == 0) {
                          node = node.left;
                      } else {
                          node = node.right;
                      }
                      reversed >>= 1;
                  }
                  return node;
              }
              public TreeNode<T> remove(int pos) {
                  if(pos <= 1) {
                      return null;
                  }
                  TreeNode<T> last = findNode(pos);
                  if(last.parent.right == last) {
                      last.parent.right = null;
                  } else {
                      last.parent.left = null;
                  }
                  this.val = last.val;
                  bubbleDown();
                  return null;            
              }   
          
              public void bubbleDown() {
                  TreeNode<T> node = this;            
                  do {
                      TreeNode<T> left = node.left;
                      TreeNode<T> right = node.right;
                      if(left != null && right != null) {
                          T max = left.val.compareTo(right.val) > 0 ? left.val : right.val;
                          if(max.compareTo(node.val) > 0) {
                              if(left.val.equals(max)) {
                                  left.val = node.val;
                                  node.val = max;                         
                                  node = left;
                              } else {
                                  right.val = node.val;
                                  node.val = max;
                                  node = right;
                              } 
                          } else {
                              break;
                          }
                      } else if(left != null) {
                          T max = left.val;
                          if(left.val.compareTo(node.val) > 0) {
                              left.val = node.val;
                              node.val = max;                         
                              node = left;
                          } else {
                              break;
                          }
                      } else {
                          break;
                      }
                  } while(true);
              }
          }
          private TreeNode<K> root;
          private int position;
          PriorityQ(){ 
              this.position = 1;
          }
          public void insert(K val) {
              if(val == null) {
                  return;
              }
              if(root == null) {
                  this.position = 1;
                  root = new TreeNode<K>(val);
                  this.position++;
                  return ;
              }
              root.insert(val, position);
              position++;     
          }
          public K remove() {
              if(root == null) {
                  return null;
              }
              K val = root.val;
              root.remove(this.position-1);
              this.position--;
              if(position == 1) {
                  root = null;
              }
              return val;
          }
          public static void main(String[] args) {
              PriorityQ<Integer> q = new PriorityQ<>();
              System.out.println(q.remove());
              q.insert(1);
              q.insert(11);
              q.insert(111);
              q.insert(1111);
              q.remove();
              q.remove();
              q.remove();
              q.remove();
              q.insert(2);
              q.insert(4);
          }
          

          }

          【讨论】:

          • 请在您的代码中添加一些 cmets 以便于理解。还要说明您的解决方案与其他解决方案有何不同/更好。
          猜你喜欢
          • 2011-11-28
          • 2011-01-02
          • 2012-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多