Three implementations of stack - Java language description

For the stack structure commonly used in data structures, its implementation is usually divided into three types:

1. Implementation based on simple arrays

2. Implementation based on dynamic array

3. Implementation method based on linked list

1. Simple array implementation

//Maximum space must be declared in advance
public class ArrayStack {
	private int top;
	private int capacity;
	private int[] array;
	public ArrayStack() {
		capacity = 3;//Declare the maximum space of the stack
		array = new int [capacity];
		top = -1;
	}
	public boolean isEmpyt() {
		return top == -1;
	}
	public boolean isStackFull() {
		return top == capacity - 1;
	}
	public void push(int data) {
		if(isStackFull()) {
			System.out.println("Stack Overflow");
		}else {
			array[++top] = data;
		}
	}
	public int pop() {
		if (isEmpyt()) {
			System.out.println("Stack is empyt");
			return 0;
		}else {
			return array[ top--];
		}
	}
	public void deleteStack() {
		top = -1;
	}
	public static void main(String[] args) {
		ArrayStack ast= new ArrayStack();
		ast.push(3);
		ast.push(7);
		ast.push(6);
		System.out.println(ast.pop());
	}
}

Limitation: The maximum size of the stack must be declared in advance and cannot be changed. Attempting to perform a push operation on a full stack will generate a stack full exception.

2. Dynamic array implementation method

In order to solve the exception of stack overflow when the stack is full, dynamic array implementation is required.

Scheme 1. When the stack is full, increase the size of the array by 1 each time, so that the total time overhead of performing n push operations is:

1+2+...+n = O(n^2), the time complexity is square level.

Option 2: Repeated doubling. The time overhead of performing n push operations in this way is:

1+2+4+8+...+n/4+n/2+n = n(1+1/2 + 1/4 + 1/8 +.... + 4/n +2/n + 1/n) = 2n = O(n). Therefore, the time overhead of n times of push by multiplying is smaller. In fact, the default implementation of stack in Java also adopts this method.

// Multiplying too much can lead to memory overflow
public class DynArrayStack {
	private int top;
	private int capacity;
	private int[] array;
	public DynArrayStack() {
		capacity = 1;
		array = new int[capacity];
		top = -1;
	}
	public boolean isEmpty() {
		return top == -1;
	}
	public boolean isStackFull() {
		return (top == capacity - 1);
	}
	public void push(int data) {
		if(isStackFull()) {
			doubleStack();
		}
		array[++ top] = data;
	}
	private void doubleStack() {
		// TODO Auto-generated method stub
		int[] newArray = new int[capacity * 2];
		System.arraycopy(array, 0, newArray, 0, capacity);
		capacity = capacity * 2;
		array = newArray;
	}
	public int pop() {
		if(isEmpty()) {
			System.out.println("Stack is Empty!");	
			return 0;
		}else {
			return array[top --];
		}
	}
	public void deleteStack(){
		top = -1;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DynArrayStack dysta = new DynArrayStack();
		dysta.push(3);
		dysta.push(7);
		dysta.push(9);
		System.out.println(dysta.pop());
		System.out.println(dysta.isEmpty());
		
	}

}

3. Stacks can also be implemented using linked lists. The push operation is implemented by inserting elements at the head of the linked list, and the pop operation is implemented by deleting the head node (the top node of the stack) of the linked list.

public class LLStack {
    private LLNode headNode;
    public LLStack() {
        this.headNode = new LLNode();
    }
    public void push(int data) {
        if(headNode == null) {
            headNode = new LLNode(data);
        }else {
            LLNode llNode = new LLNode(data);
            llNode.setNext(headNode);
            headNode = llNode;
        }
    }
    public int top() {
        if (headNode == null) {
            return 0;
        }else {
            return headNode.getData();
        }
    }
    public int pop() {
        if(headNode == null) {
            System.out.println("stack Empty!");
            return 0;
        }else {
            int data = headNode.getData();
            headNode = headNode.getNext();
            return data;
        }
    }
    public boolean isEmpty() {
        if(headNode == null)    return true;
        else return false;
    }
    public void deleteStack() {
        headNode = null;
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LLStack llst = new LLStack();
        llst.push(6);
        llst.push(7);
        System.out.println(llst.pop());
    }
    public class LLNode {
        private int data;
        private LLNode next;
        public LLNode() {
            
        }

        public LLNode(int data) {
            this.data = data;
        }
        public int getData() {
            return data;
        }
        public void setData(int data) {
            this.data = data;
        }
        public LLNode getNext() {
            return next;
        }
        public void setNext(LLNode next) {
            this.next = next;
        }
        
    }

}

The only trouble with this method is that when deleting the linked list, if the linked list implemented by C++ is used, then deleting the linked list requires a circular linked list to delete all elements, and its time complexity is O(n). The head node can be left blank.

The above are the three implementation mechanisms of the stack. The second method is adopted by default in Java, and the initial size of the stack is 5000.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324770812&siteId=291194637