优先级队列(从头开始)和链表

Posted

技术标签:

【中文标题】优先级队列(从头开始)和链表【英文标题】:Priority queue (from scratch) and linked lists 【发布时间】:2015-07-16 20:40:05 【问题描述】:

我正在尝试从一些无序的原始数据(String1...Priority10、String2...IntPriority2 等)创建一个链接列表,并且在概念化如何排序时遇到了麻烦,我无法为优先级队列编写一个好的方法。我需要获取将每个对象按顺序排入队列的方法,而不是在最终链表上使用排序算法,或者使用任何 LinkedList 或 PriorityQueue 本身。

我的入队方法,这里没什么难的:

    public class ObjectQueue
Object front = null;           //points to first element of the queue
Object prev = null;            //points to last element of the queue 
  /**
 * Creates an object of Object and adds to the class queue
 * @param name of object
 * @param rank of priority sort
 */
public void enQueue(String name, int rank)

    Object current = new Object(name, rank);  //uses current entry String as name, int as rank

    if(isEmpty())               //if empty, add element to front
    
        front = current;
    
    else                        //if elements exist, go to end and create new element
    
        prev.next = current;
    
    prev = current;

还有我遇到问题的优先排序和添加方法:

/**
 * Adds each object and rank on a ascending rank basis
 * @param filename name of data file
 * @throws exc in case of missing file
 */
public void addPriority(String filename) throws IOException

    try
    
    File inFile = new File(filename);           //inst. file import
    Scanner read = new Scanner(inFile);         //inst. scanner object

    String name1 = read.next();              //scanner reads next string, primes at front
    int rank1 = read.nextInt();              //reads next int, assigns to rank

    while (read.hasNext())                      //reads until end of text
    
        String name2 = read.next();              //next string of next Object to be tested
        int rank2 = read.nextInt();              //rank to test rank1 against

        if (rank1 > rank2)                      //if current is higher priority than test
        
            enQueue(name1, rank1);              //enqueue the current object
            name1 = name2;                      //move test name down to current
            rank1 = rank2;                      //move test rank down to current
        
        else
        
            enQueue(name2, rank2);              //enqueue the current object
        
    
    read.close();                               //ends read when empty

    
    catch(Exception exec)
    
        System.out.println("Error: file not found.");
    


我需要一个单一的方法来预先对对象进行排序而不将它们发送到列表中,或者在运行中对它们进行一次正确排序,但我的想法已经用完了。

【问题讨论】:

你不需要排序来实现优先队列。你应该阅读堆。另外你为什么使用链表而不是数组?这是非常低效的方法 我需要为此使用链表,而不是数组。并且没有 LinkedList 对象,只是我自己的从头开始。 然后阅读二进制堆并尝试使用 双重 链表 (en.wikipedia.org/wiki/Heap_%28data_structure%29) 来实现它们 【参考方案1】:

从概念上讲(忽略实现)优先级队列非常简单。它需要能够添加具有优先级的项目,并且需要能够获得具有最高(或者,在某些实现中,最低)优先级的项目。有时包含的另一个约束是,对于具有相同优先级的两个项目,必须首先检索首先添加的项目。

这就是概念。为了让我们帮助您,您可能需要提供更多关于您的优先级队列应该如何工作的详细信息。对于以下注释,我将假设: - 首先检索最高优先级 - 应按插入顺序检索同等优先级

查看实现,只要允许插入并且保留插入顺序,底层结构几乎可以是任何集合。传统的实现是堆,因为它们有效地使用内存并且速度非常快,但是链表(单或双)在功能上很好。

显然,优先队列意味着检索顺序。这可以在插入或检索时实现。同样,此决定将由使用情况决定,而且您的实现似乎可以忽略这些因素。

因此,为了简单起见,我的建议是在插入时而不是在检索时进行排序。在不向您提供实际代码(我假设这是您的任务)的情况下,这是一个可以实现插入时间优先级队列的基本算法。

class PriorityItem 
    private final Item item;
    private final int priority;


Collection<PriorityItem> queue;

void insert(Item item, int priority) 
    PriorityItem element = new PriorityItem(item, priority); 
    if queue is not empty 
        step through queue 
            if current.priority < priority 
                insert element here
                return
            
        
    
    add element to end queue

然后检索是微不足道的:它只是队列中的第一项。

【讨论】:

以上是关于优先级队列(从头开始)和链表的主要内容,如果未能解决你的问题,请参考以下文章

算法:栈和队列

使用链表的优先队列

Java 链表优先队列

如何使用优先队列对链表进行排序

带链表的 C++ 优先级队列类

在java中,啥是队列?