【问题标题】:How to use generic in Stack data structure?如何在 Stack 数据结构中使用泛型?
【发布时间】:2015-07-07 21:29:20
【问题描述】:

我已经用 Java 实现了一个简单的堆栈,它可以工作。它使用 Node 类来保存堆栈 int 值。现在,我正在计划另一个类 NodeWithMin,它应该包含所关注的节点以及从节点到底部的最小值。这意味着当我将获得堆栈的顶部节点时,我将拥有节点和堆栈的最小值。

我想使用泛型与 Stack 类来切换我想插入的任何类(Node / NodeWithMin) .所以,最后它会是一些东西 -

public class myStack extends Stack< Node or NodeWithMin >{

}

堆栈需要在哪里

class Stack<T>{

}

如果您需要进一步澄清问题,请告诉我。我了解 Stack 类中的某些方法需要更改。关于我该怎么做的任何建议?谢谢。

import java.util.*;

class Node {

    public Node above;
    public Node below;
    public int data;

    public Node(int data) {

        this.data = data;
    }

}

class NodeWithMin {

    public NodeWithMin above;
    public NodeWithMin below;

    public int data;
    public int min;

    public NodeWithMin(int data , int min){

        this.data = data;
        this.min = min;
    }

}


class Stack {

    private int capacity;
    public Node top;
    public Node bottom;
    public int size;

    HashSet<Integer> hashSet = new HashSet<Integer>();

    public Stack ( int cap ){

        this.top = null;
        this.bottom = null;
        this.capacity = cap;
        this.size = 0;
    }

    public static int randomInt(int n) {

        return (int) (Math.random() * n);
    }

    public static int randomIntInRange(int min, int max) {

        return randomInt(max + 1 - min) + min;
    }

    public boolean isFull() { 
        return capacity == size; 
    }

    public void join (Node newNode, Node stackTop) {

        // not empty stack 
        if ( stackTop != null ){

            stackTop.above = newNode;
        }

        // if the new node is not null
        // previous top is now below of the inserted node which is the current top 
        if ( newNode != null){

            newNode.below = stackTop;
        }
    }

    public boolean push(int v) {

        if (size >= capacity) 
            return false;

        size++;
        Node n = new Node(v);
        if (size == 1) bottom = n;
        join(n, top);

        // define the new top 
        top = n;

        // pushing is sucessful 
        return true;
    }

    public int min(){

        if ( top == null) return -1;

        Node curr = this.top;
        int min =-1 ; 

        System.out.println("\n\n");
        while( curr != null){

            hashSet.add(curr.data);
            curr = curr.below;
        }

        System.out.println();
        min = Collections.min(hashSet);

        return min; 
    }

    public int pop() {

        Node t = top;
        top = top.below;
        size--;
        return t.data;
    }

    public int peek (){

        Stack myStack = this; 
        return myStack.top.data ;

    }

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

    public int removeBottom() {

        Node b = bottom;
        bottom = bottom.above;
        if (bottom != null) bottom.below = null;
        size--;
        return b.data;
    }

    public void display(){

        if ( top == null) return;

        Node curr = this.top;
        int min =-1 ; 

        System.out.println("\n\n");
        while( curr != null){

            System.out.println( curr.data);

            curr = curr.below;

            if ( curr != null){

                System.out.println("↑");
            }
        }

        System.out.println();
    }

    public static void main ( String[] args ){

        // System.out.println("\nMy stack is here \n");
        Stack s = new Stack(5);

        for (int j = 0; j < 5; j ++){
            s.push( randomIntInRange(0, 100) );
        }

        s.display();
        System.out.println("the min of the stack is =  "+ s.min());

    }

}

【问题讨论】:

  • 快速谷歌搜索给出:java2s.com/Tutorial/Java/0200__Generics/GenericclassStack.htm。希望这可以帮助您入门。
  • 感谢您的链接。如您所见,我可以得到最低限度,但是,我的想法也略有不同。所以,当我 peek() 顶部时,它也应该给我 Stack 的最小值和顶部值。我可以在没有泛型的情况下实现它,但是,我想学习它。谢谢。
  • 在这种情况下,您应该让您的 Node 和 NodeWithMin 实现一个通用接口,然后您的 Stack 就可以使用该接口。

标签: java generics data-structures


【解决方案1】:

在我看来NodeWithMinNode 做的基本事情一样,而且它还有 Min 的东西。所以我会让NodeWithMin 扩展Node。然后你可以将 MyStack 声明为:

public class myStack extends Stack< ? extends Node > {
...
}

MyStack 现在可以与NodeNodeWithMin 一起使用。

至于Stack,最值得注意的问题是它被写入显式依赖Node 的实例。这是一个问题,因为您说您希望Stack 是通用的,能够采用任何T。因此,您必须以正确的顺序保留所有 T 实例,而不是期望它们记住谁在之前或之后,这与您尝试对 NodeWithMin 执行的操作不一致。

所以我认为你需要重新考虑你希望这些东西有多通用。如果 Stack 真的应该是完全通用的,即它应该能够以 LIFO 顺序保留任何类型的对象,那么 MyStack 将不得不覆盖 Stack 中的大部分方法才能使用它知道Node。 OTOH,如果您真正想做的只是按 LIFO 顺序保留一堆 Node(或其子类型)对象,然后完全抛弃 Stack,直接转到 MyStack

哦,顺便说一句,你使用HashSet 很麻烦。由于您将其实例化一次,因此您冒着保留Stack 中不再存在的东西的风险,即您可以弹出当前最小值,但min() 方法会继续返回它。最好在 min() 方法中使其成为局部变量,因为这是唯一使用它的地方。

此外,为了使用Collections.min() 方法,Stack 中的所有对象都必须实现Comparable,这反对使用泛型T。您可能希望将min() 方法移动到MyStack(假设您将Node 更改为实现Comparable)。

【讨论】:

  • 感谢您写的这么详细。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-24
  • 1970-01-01
相关资源
最近更新 更多