1.实现栈的两种方式:
数组实现:如果申请的初始化大小太大会造成空间的浪费,如果申请的空间太小则会需要经常扩充空间
public class MyStack<T> {
private int top;//top指针(数值为下标)
private T[] arr;//数组
public MyStack(int size){
top = 0;
arr = (T[]) new Object[size];
}
boolean isEmpty(){
return top ==0;
}
public void push(T number){//入栈操作
arr[top] = number;
top ++;
}
public void pop(){//出栈
if (top == 0){
System.out.println("当前栈已空");
}
else arr[top-1] = null;
top --;
}
public boolean isFull(){
if (top == arr.length){
return true;
}else return false;
}
public T getTop() {
if (top==0){
return null;
}
return arr[top-1];
}
@Override
public String toString() {
return "MyStack{" +
"top=" + top +
", arr=" + Arrays.toString(arr) +
'}';
}
}
链式实现:使用方便,至于在需要使用的时候才会申请空间,但是需要额外的空间存储数据域
public class MyStackLinked<T> {
class Node<T>{
T data;
Node<T> next;
}
private Node<T> head;//带头节点的链表
public MyStackLinked(){
head = new Node<>();
head.data = null;
head.next = null;
}
private void push(T value){
Node node = new Node();//每次入栈都开辟新的节点
node.data = value;
node.next = head.next;//插入到头结点的后面
head.next = node;
}
private void pop (){
Node<T> p = head;//头删
if (p.next!=null){
head.next = p.next.next;
}else
{
System.out.println("当前栈为空");
}
}
private boolean isEmpty(){
return head.next == null;
}
private int getSize(){
Node<T> p = head;
int count = 0;
while (p.next!=null){
p = p.next;
count++;
}return count;
}
private void getAll(){
Node<T> p = head;
while (p.next!=null){
System.out.println(p.next.data);
p = p.next;
}
}
2.实现队列的方式:
数组实现:
public class MyQueue <T>{
private int front;
private int rear;
private T arr[];
public MyQueue(int size){
front = 0;
rear = 0;
arr = (T[]) new Object[size];
}
public void add(T number){
arr[rear] = number;
rear++;
}
public void remove(){
if (rear == front){
System.out.println("此队列已空");
}else {
arr[front]=null;
front++;
}
}
public int size(){
return front-rear;
}
public boolean isEmpty(){
return front==rear;
}
@Override
public String toString() {
return "MyQueue{" +
"front=" + front +
", rear=" + rear +
", arr=" + Arrays.toString(arr) +
'}';
}}
3.如何反转栈的所有元素
public class Reverse{
private static void changeToTop(MyStack<Integer> stack){
if (stack.isEmpty()){
return;
}
int top = stack.getTop();
stack.pop();
if (stack.isEmpty()!=true){
changeToTop(stack);
int top2 = stack.getTop();
stack.pop();
stack.push(top);
stack.push(top2);
}else stack.push(top);
}
public static void re(MyStack<Integer> stack){
if (stack.isEmpty()){
return;
}
changeToTop(stack);
int top = stack.getTop();
stack.pop();
re(stack);
stack.push(top);
}
}
4.如何根据入栈顺序判断可能的出栈顺序
/*
实现给定一个栈的入站顺序求给出的任意一种出栈序列是不是一种可能的入栈顺序;
使用一个栈来模拟入栈顺序
push序列依次入栈,如果遇到栈顶元素等于pop序列的第一个元素,就将栈顶元素出栈,并将pop序列后移,否则,将push序列继续入栈
若push序列已经全部入栈,但是pop序列还未全部遍历并且栈顶元素不等于当前pop元素,则不是
若栈为空且pop已经遍历结束,则是
*/
public class PopSerial<T> {
private MyStack stack;
public PopSerial() {
stack = new MyStack(5);
}
public void PopS(T arr[],T brr[]) {
int j = 0;
for (int i= 0;i<arr.length;i++ ){
stack.push(arr[i]);
try {
while (stack.getTop().equals(brr[j]) && j < brr.length) {//j < 5
stack.pop();
j++;
if (j==5){
break;
}
}
}catch (ArrayIndexOutOfBoundsException e){
System.out.println(j);
System.out.println(stack);
}
}
System.out.println(j+""+stack);
if (j!=brr.length && (stack.getTop().equals(brr[j-1]))!=true){
System.out.println("不是一个可能的出栈顺序");
}
if (stack.isEmpty()==true&&j==brr.length){
System.out.println("是一个可能的出栈顺序");
}
}
}
5.如何用两个栈模拟一个队列
public class StackToqueue<T> {
private MyStack<T> myStack = new MyStack<>(5);
private MyStack<T> myStack2 = new MyStack<>(5);
public void add(T value) {
myStack.push(value);
}
public T remove() {
if (myStack2.isEmpty()) {
while (!myStack.isEmpty()) {
myStack2.push(myStack.getTop());
myStack.pop();
}
}
T top = myStack2.getTop();
myStack2.pop();
return top;
}