Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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
Java 通过二叉树结构实现的二叉堆_Java_Data Structures - Fatal编程技术网

Java 通过二叉树结构实现的二叉堆

Java 通过二叉树结构实现的二叉堆,java,data-structures,Java,Data Structures,对于一个赋值,我们被指示创建一个通过二进制堆实现的优先级队列,而不使用任何内置类,我通过使用数组存储排队对象成功地做到了这一点。然而,我感兴趣的是学习如何使用实际的树结构实现另一个队列,但在这样做的过程中,我遇到了一些问题 如何跟踪要在其上执行插入和删除操作的节点?我已尝试使用链表,在插入每个节点时将其追加-从第一个列表节点开始添加新的子节点,然后从另一端删除。但是,当元素在树中重新排列时,由于子元素被添加到错误的位置,这一点就会出现问题 编辑:也许我应该澄清一下——我不确定如何才能找到最后一片

对于一个赋值,我们被指示创建一个通过二进制堆实现的优先级队列,而不使用任何内置类,我通过使用数组存储排队对象成功地做到了这一点。然而,我感兴趣的是学习如何使用实际的树结构实现另一个队列,但在这样做的过程中,我遇到了一些问题

如何跟踪要在其上执行插入和删除操作的节点?我已尝试使用链表,在插入每个节点时将其追加-从第一个列表节点开始添加新的子节点,然后从另一端删除。但是,当元素在树中重新排列时,由于子元素被添加到错误的位置,这一点就会出现问题


编辑:也许我应该澄清一下——我不确定如何才能找到最后一片被占用的叶子和第一片未被占用的叶子。例如,我总是能够告诉最后一个插入的叶子,但如果我要删除它,我如何知道下次删除该项目时要删除哪个叶子?插入也是一样——在当前叶同时包含两个子叶之后,我如何知道跳到下一个叶呢?

二进制堆的树实现使用一个[或几乎满的树:除最深的树外,每一层都满了]。
您总是“知道”哪一个是最后一个被占用的叶-从中删除[并且在它更改后修改它是O(logn),所以这不是问题],并且您总是“知道”哪一个是第一个未被占用的叶,在其中添加元素[而且,在它更改后修改它也是O(logn)]

算法思想非常简单:
插入:将元素插入到第一个未占用的叶中,并使用[sift up]将该元素放到堆中的正确位置

delete_min:用最后一个占用的叶替换第一个元素,并移除最后一个占用的叶。然后,对堆进行筛选


编辑:请注意,
delete()
可以对任何元素执行操作,但不仅仅是头部-找到要用最后一片叶子替换的元素将是O(n),这将使此操作变得昂贵。因此,
delete()
方法[除头部之外],通常不是堆数据结构的一部分。

我真的想这么做了将近十年。今天终于坐下来写了。任何想要它的人都可以使用它。我受到Quora创始人的启发,重新学习堆。显然,有人问他如何在谷歌手机屏幕上的一组n点中找到K点。显然,他的答案是使用最大堆并存储K值,并在堆的大小超过K后删除最大元素。该方法非常简单,最坏的情况是nlog K,在大多数排序情况下,它优于n^2。下面是代码

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

    }

    public 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();
    }

    public 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;
                }
            }
        }
        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));
    }
}

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;
    }

}
import java.util.ArrayList;
导入java.util.List;
/**
*@作者Harish R
*/
公共类HEAPPractice{
私人名单;
公共列表getHeapList(){
回归heapList;
}
public void setHeapList(列表heapList){
this.heapList=heapList;
}
私人治疗;
公共卫生许可证(){
this.heapList=new ArrayList();
this.heapSize=heapList.size();
}
公共无效插入(T项){
if(heapList.size()=0){
heapList.添加(项目);
}否则{
siftUp(项目);
}
}
公共作废siftUp(T项){
heapList.添加(项目);
heapSize=heapList.size();
int currentIndex=heapSize-1;
而(当前索引>0){
int parentIndex=(int)数学层((currentIndex-1)/2);
T parentItem=heapList.get(parentIndex);
if(parentItem!=null){
如果(项比较到(父项)>0){
heapList.set(父索引,项);
heapList.set(currentIndex,parentItem);
currentIndex=父索引;
继续;
}
}
打破
}
}
公营部门不删除(){
if(heapList.size()=0){
返回null;
}
if(heapList.size()=1){
T item=heapList.get(0);
heapList.remove(0);
退货项目;
}
返回siftDown();
}
公共部门{
T item=heapList.get(0);
T lastItem=heapList.get(heapList.size()-1);
heapList.remove(heapList.size()-1);
heapList.set(0,最后一项);
heapSize=heapList.size();
int currentIndex=0;
while(当前索引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);
}