如何在Stack数据结构中使用泛型?

时间:2015-07-07 21:29:20

标签: java generics data-structures

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

我想在 Stack 类中使用泛型来切换我想用它插入的任何类( Node / NodeWithMin ) 。所以,最后它会是 -

public class myStack extends Stack< Node or NodeWithMin >{

}

Stack需要

的地方
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());

    }

}

1 个答案:

答案 0 :(得分:1)

我认为NodeWithMinNode的基本内容相同,而且它有Min的内容。所以我要NodeWithMin延长Node。然后你可以将MyStack声明为:

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

MyStack现在可以使用NodeNodeWithMin

对于Stack,最值得注意的问题是它被编写为明确依赖Node的实例。这是一个问题,因为您说您希望Stack是通用的,能够接受任何T。因此,您必须按正确的顺序保留所有T个实例,而不要让他们记住之前或之后的人,这与您尝试使用NodeWithMin的内容不一致。< / p>

所以我认为你需要重新思考你想要这些东西的通用性。如果Stack应该是完全通用的,即它应该能够以LIFO顺序保留任何类型的对象,那么MyStack将必须按顺序覆盖Stack中的大部分方法利用它对Node的了解。 OTOH,如果您真正想做的就是以LIFO顺序保留一堆Node(或其子类型)对象,然后完全抛弃Stack并直接转到MyStack

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

此外,为了使用Collections.min()方法,Stack中的所有对象都必须实现Comparable,并且反对使用通用T。您可能希望将min()方法移至MyStack(假设您更改Node以实施Comparable)。