栈是指只在表尾进行插入和删除的线性表,后进先出(List In First Out)
栈在java中的定义,栈的入栈 出栈 检验空满栈 栈的动态扩容 降容 输出等操作
栈结构体的结构部分,在java直接写在一个类里面。
Object[] elements;
int top=-1;//始终指向栈顶
int lengthStack;
package com.javase.datastruct.stack;
import com.sun.javaws.IconUtil;
import java.util.Arrays;
public class Stack {
public static void main(String[] args) {
/*栈的基本测试*/
MyStack s=new MyStack(5);
System.out.println("栈的初始状态"+s);
if(s.isEmpty()){
//入栈
System.out.println("操作1:入满栈");
for(int i=s.top+1;i<s.lengthStack;i++) {
s.push(i);
}
System.out.println("——————————————————————————————");
System.out.println("检验栈是否为满:"+s.isFull());
System.out.println("操作2:出栈");
for(int i=s.top;i>=0;i--) {
s.pop();
}
}
System.out.println("检验栈是否为空:"+s.isEmpty());
System.out.println("——————————————————————————————");
//存放类
System.out.println("操作3:数组中放入类");
Student student=new Student("张三",22);
s.push(student);
System.out.println("显示所有的栈元素");
System.out.println(s);
s.pop();//单独出类
System.out.println(s);
/*数组的扩容*/
//之前用C++编写的时候 知道动态结构
//昨天有瞄到数组的合并,想了一下 或许可以用到 试试 发现不行 因为数组大小在栈这个类创建的时候就定义了
//MyStack s2=new MyStack(3);
/*if(s.isEmpty()){
for(int i=s.top+1;i
//只能用动态结构
if(s.isEmpty()){
for(int i=s.top+1;i<s.lengthStack;i++) {
s.push(i);
}
}
if(s.isFull()){
System.out.println("——————————————————————————————");
System.out.println("操作4:扩容");
s.addSize(2);
for(int i=s.top+1;i<s.lengthStack;i++){
s.push(i);
}
/* for(int i=s.top;i>=0;i--) {
s.pop();
}*/
System.out.println("——————————————————————————————");
System.out.println("操作5:降容,并显示出被挤出的元素");
System.out.println(s);
s.subSize(2);
System.out.println("检验,降容后的栈");
System.out.println(s);
}
}
}
//静态栈的实现
//先进后出
class MyStack{
/*构造基本结构*/
Object[] elements;
int top=-1;//始终指向栈顶
int lengthStack;
//构造一个构造方法 实现调用的时候,确定栈的长度
public MyStack(int lengthStack) {
this.lengthStack = lengthStack;
elements= new Object[lengthStack];//同时为栈内的数组产生一个具体内存空间的对象
}
//判断是否已经满
public boolean isFull(){
return top==this.lengthStack-1;
}
public boolean isEmpty(){
return top==-1;
}
//压栈
public void push(Object obj){
if(!isFull())//如果未满
elements[top+1]=obj;
else{
System.out.println("栈满");
return;
}
top++;
}
//出栈
public Object pop(){
if(isEmpty()){
System.out.println("空栈,无需弹出");
return 0;
}
Object obj1=elements[top];
System.out.println("出栈:"+obj1);
elements[top]=null;
top--;
return obj1;
}
@Override
public String toString() {
return "MyStack{" +
"elements=" + Arrays.toString(elements) +
'}';
}
//增加一个栈的动态扩容
public void addSize(int loadFactor){
lengthStack=(int)(lengthStack*loadFactor);
//Object[] elements=(Object[]) new Object(lengthStack);
this.elements=Arrays.copyOf(elements,lengthStack);
}
//降容 降低两个
public void subSize(int subFactor){
if(this.lengthStack-subFactor>=0){
for(int i=top;i>(this.lengthStack-1-subFactor);i--){
this.pop();
}
this.lengthStack=this.lengthStack-subFactor;
this.elements=Arrays.copyOf(elements,this.lengthStack);
}
}
}
//在数组中存放一个类
class Student{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
——————
之前在cpp里会用头文件申明一下方法
java就可以用到前些天学的接口
package com.javase.datastruct.stack;
public interface StackMethod {
//接口包含常量 和 未实现的抽象方法
boolean isFull();
boolean isEmpty();
void push(Object obj);
Object pop();
void addSize(int loadFactor);
void subSize(int subFactor);
}
class MyStack implements StackMethod
注:复习的java自带函数不用在接口中写出来
public void addSize(int loadFactor){
lengthStack=(int)(lengthStack*loadFactor);
//Object[] elements=(Object[]) new Object(lengthStack);
this.elements=Arrays.copyOf(elements,lengthStack);
}
数组扩容还可以用System.arraycopy();库函数
public void subSize(int subFactor){
if(this.lengthStack-subFactor>=0){
for(int i=top;i>(this.lengthStack-1-subFactor);i--){
this.pop();
}
this.lengthStack=this.lengthStack-subFactor;
this.elements=Arrays.copyOf(elements,this.lengthStack);
}
}
这一篇写的很详细了
java实现
package com.javase.datastruct.stack;
import java.util.Arrays;
import java.util.Scanner;
public class StackShared {
public static void main(String[] args) {
MyStack1 s2=new MyStack1(5);
System.out.println("栈的初始状态"+s2);
if(s2.isEmpty()){
//入栈
System.out.println("操作1:入栈,“左起入栈输入1,右起入栈输入2”"+'\n'+"请选择:");
Scanner scanner = new Scanner(System.in);
int stnum=scanner.nextInt();
System.out.println("stnum:"+stnum);
while(stnum!=1&&stnum!=2){
System.out.println("输入错了,请重新输入!");
stnum=scanner.nextInt();
}
if(stnum==1){//左输入
for(int i=0;i<(s2.lengthStackShare+1)/2;i++){
s2.push(i,stnum);
}
for(int i=0;i<(s2.lengthStackShare+1)/2;i++){
System.out.println(s2.pop(i,stnum));
}
}else{
for(int j=s2.lengthStackShare;j>=s2.lengthStackShare/2;j--){
s2.push(j,stnum);
}
for(int j=s2.lengthStackShare;j>=s2.lengthStackShare/2;j--){
System.out.println(s2.pop(j,stnum));
}
}
}
}
}
class MyStack1 implements StackSharedMethod{
Object[] elements;
private int top1=-1;
private int top2;
int lengthStackShare;
public MyStack1(int lengthStackShare) {
this.lengthStackShare = lengthStackShare;
elements=new Object[this.lengthStackShare];
top2=this.lengthStackShare;
}
public boolean isFull(){
/*if(top1+1==top2||top1==this.lengthStackShare-1||top2==0)
return true;*/
return top1+1==top2;//上面括号处意思等同于这步
}
public boolean isEmpty(){
return top1==-1&&top2==this.lengthStackShare;//只有两个顶点指针 都在最顶端 才是为空栈
}
public int push(Object obj,int stacknumber){//对于两端进元素,需要一个判别式对其进行判断
if(this.isFull())
return 0;
else{
if(stacknumber==1){
top1++;
this.elements[top1]=obj;
}
if(stacknumber==2){
top2--;
this.elements[top2]=obj;
}
}
return 1;
}
public Object pop(Object obj,int stacknumber){
Object value = null;
if(this.isEmpty())
return 0;
if(stacknumber==1){
value=this.elements[top1];
this.elements[top1]=null;
top1--;
}
if(stacknumber==2){
value=this.elements[top2];
this.elements[top2]=null;
top2++;
}
return value;
}
@Override
public String toString() {
return "MyStack1{" +
"elements=" + Arrays.toString(elements) +
'}';
}
}
Object[] elements;
private int top1=-1;
private int top2;
int lengthStackShare;
写在一个里面,同时它的实现方法可以写在同一个类里,也可以使用继承实现。
class Node{
Object data;//元素
Node next;//相当于指针 指向下一个
public Node(){
}
public Node(Object data) {
this.data = data;
//this.next = next;
}
}
链式结构的实现部分
Node top; 是一直指向顶点的一个指针
size用来记录栈的节点个数,可灵活使用
class stackLNode implements StackLink{
Node top;//存放栈顶点结点
private int size;//栈元素个数 每次创建一个栈 其内存都可以不一样 所以需要设置
public stackLNode(){//创建一个空栈
InitStack();
}
private void InitStack(){
top=null;
this.size=0;
}
public stackLNode(Node t, int size) {//指定一个栈 t应该是一个新建的结点
this.top = t;
this.size = size;
}
public boolean isEmpty(){
return this.size==0;
}
public void push(Object data){
Node node=new Node(data);//建立一个新的栈结点 并赋予元素
node.next=top;//将原顶点的空信息 赋予新结点的next
top=node;// 然后又使得新建立的结点为top top是存放栈顶点的结点 最新的一个就是栈顶
size++;
System.out.println(data+"压栈成功");
}
public Object pop(){
//出栈 栈的出栈原则 出栈顶那个元素
Object value;
if(isEmpty()){
System.out.println("空栈");
return 0;
}
value = top.data;//因为top是指向栈顶的指针
Node Oldtop=top;
top=top.next;
Oldtop=null;
size--;
return value;
}
@Override
public String toString() {
return "stackLNode{" +
"top=" + top +
'}';
}
}
队列遵循一个先进先出的原则
而栈遵循先进后出,所以栈有压栈 弹栈的原则 都是离栈顶最远的结点元素
误区:1**********当 队列不为空时 头指针永远指向第一个位置---------》》》实际上头指针如果永远在第一个的话,那么后面出队,就要每次都移动了,
所以解决方法是头指针始终在第一个元素那,所以对应只有当头指针和尾指针相等时 即为空队列
//队列的顺序存储结构+链式结构
//队列遵循一个先进先出的原则
//而栈遵循先进后出,所以栈有压栈 弹栈的原则 都是离栈顶最远的结点元素
import java.util.Arrays;
import java.util.Scanner;
/*误区:1**********当 队列不为空时 头指针永远指向第一个位置---------》》》实际上头指针如果永远在第一个的话,那么后面出队,就要每次都移动了,
所以解决方法是头指针始终在第一个元素那,所以对应只有当头指针和尾指针相等时 即为空队列
* 误区:2**********
* */
public class queueNode implements queueNodeinterface {
Object[] obj;
int head=0;
int tail=0;//当队列不为空时 尾指针永远指向最后一个元素的下一个位置
int lengthqueue;
public queueNode(int lengthQueue) {
this.lengthqueue = lengthQueue;
obj=new Object[this.lengthqueue];
}
public boolean isFull(){
return this.tail==this.lengthqueue;
}
public boolean isEmpty(){
return this.head==this.tail;
}
public int EnQueue(){
if(isEmpty()){
System.out.println("空队列,请输入元素入队:");
//空队列的话,为了节约空间,将头指针和尾指针重置
this.head=this.tail=0;
Scanner scanner=new Scanner(System.in);
//StringBuffer s=scanner.nextLine();//遇到一个问题 那就是StringBuffer如何和Scanner结合
//StringBuffer s=new StringBuffer("a");
String s=scanner.nextLine();
obj[this.head]=s;
++this.tail;
return 0;
}
if(!isFull()){
System.out.println("队列未满,请输入元素入队");//入队列时 从队尾入 然后队尾指针往后指一个 ***保证每次入队结束之后队尾所指向的都是为空结点
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
obj[this.tail]=s;
++this.tail;
return 0;
}
else{
/*对列 即不为空 又满了,进行扩队列处理*/
//*********************************************************扩队列处理
System.out.println("队列满,请选择操作:1:出队,2:队列扩容,3:跳出循环");
Scanner scanner=new Scanner(System.in);
int select=scanner.nextInt();
while(select!=1&&select!=2&&select!=3){
System.out.println("输入有错,请重新输入!");
select=scanner.nextInt();
}
if(select==3){
return 0;
}
if(select==1){
System.out.println("出队----》请选择出队人数!");
int dequeuenum=scanner.nextInt();
while(dequeuenum>0){
DeQueue();
--dequeuenum;
}
}else{
System.out.println("队列动态扩容:请选择扩容的容量!");
int expansion=scanner.nextInt();
this.lengthqueue=(int)(this.lengthqueue*expansion);
this.obj= Arrays.copyOf(obj,lengthqueue);//扩容
int i=expansion;
while(i>0){
this.EnQueue();
--i;
}
}
return 0;
}
}
public Object DeQueue(){
Object revalue=null;
if(!this.isEmpty()){//如果是非空的话
revalue=obj[this.tail-1];
obj[this.tail-1]=null;
--tail;
}else{
System.out.println("空队列 无法返回");
}
System.out.println("出队元素:"+revalue);
return revalue;
}
@Override
public String toString() {
return "queueNode{" +
"obj=" + Arrays.toString(obj) +
'}';
}
}
接口部分
public interface queueNodeinterface {
boolean isFull();
boolean isEmpty();
int EnQueue();
Object DeQueue();
}
测试部分
//队列是指一端进 一端出的线性表
public class queueTest {
public static void main(String[] args) {
queueNode q=new queueNode(5);
System.out.println("检查是否为满队列:"+(q.isFull()?"满队列":"队列未满"));
System.out.println("检查是否为空队列:"+(q.isEmpty()?"空队列":"队列不空"));
q.EnQueue();
q.EnQueue();
q.EnQueue();
q.EnQueue();
q.EnQueue();
q.EnQueue();
System.out.println(q.toString());;
}
}
链表的结点
class Node{
Object element;
Node head;//这个用于指向有元素的的第一个结点
Node tail;//指向尾结点
//Node next;
public Node(Object element) {
this.element = element;
}
public Node() {
}
}
实现部分
class queueNodeLink{
Node node;
Object data;
int size=0;
public queueNodeLink(){
InitQueue();
}
public void InitQueue(){//生成一个头结点
node=new Node();
node.head=null;
node.tail=null;
//node.next=null;
System.out.println("请输入队长的元素");
Scanner scanner=new Scanner(System.in);
node.element=scanner.nextLine();
this.size++;
}
public void EnQueue(){
System.out.println("请输入一个元素:");
Node n=new Node();//创造一个新的结点
Scanner scanner=new Scanner(System.in);
n.element=scanner.nextLine();
Node tem=node;//我要找到null的上一个结点
while(tem.tail!=null){
tem=tem.tail;
}
//当tem.tail为空时
tem.tail=n;
n.head=tem;
n.tail=null;
this.size++;
}
public int DeQueue(){
if(this.isEmpty()){//当队列为空时!
System.out.println("空队列,无法出队,请选择是否要进行入队操作?------1为进行入队操作,2为终止此处操作");
Scanner scanner=new Scanner(System.in);
int s=scanner.nextInt();
while(s!=1&&s!=2){
System.out.println("输入错误,重新输入:");
s=scanner.nextInt();
}
if(s==1){
System.out.println("请选择插入次数:");
int k=scanner.nextInt();
while(k<=0){
System.out.println("输入错误,重新输入:");
k=scanner.nextInt();
}
this.InitQueue();
for (int i = 0; i <k-1 ; i++) {
this.EnQueue();
}
this.DeQueue();
}else{
System.out.println("出队失败!终止***");
return 0;
}
}
System.out.println("请选择出队个数:");
Scanner scanner=new Scanner(System.in);
int d=scanner.nextInt();
while(d>this.size||d<=0){
System.out.println("输入错误,请重新输入:");
d=scanner.nextInt();
}
//Node next=node;
Node temnode=null;
Object value=null;
for (int i = 0; i <d; i++) {
value=node.element;//获取元素
temnode=node;//存储当前结点
node=node.tail;//指向下一个
temnode=null;//释放该结点
size--;
System.out.println("出队:"+value);
}
return 0;
}
public boolean isEmpty(){
return this.size==0;//size等于0 即为空
}
public void Pritqueue(){
if(!isEmpty()){//队列不空时
Node t=node;
for (int i = 0; i <this.size ; i++) {
System.out.println(t.element);
t=t.tail;
}
}else{
System.out.println("队列空 无法打印");
}
}
}
应用两个栈实现一个队列,分析运行时间
算法图解:如何用两个栈实现一个队列?
一开始写的是 实现了如下功能,还出栈的时候转移到另外一个队列中 虽然也没错
但是我理解错了问题的含义
借助栈先进后出的原则
两个栈一起用就实现了先进先出和队列一样
负负得正的意思
在入队列的时候,是将开始入A栈的元素,一起转移到B栈中,所以时间复杂度为O(n)
出队列的时候就是这里也是O(n)
看算法吧 也可以改成只出一个
然后在重新入队列的时候 需要判断一下B栈中是否还有元素
import java.util.Scanner;
public class TwoStacksAQueue {
public static void main(String[] args) {
Test t=new Test();
t.EnQueuebyStacks();
t.DeQueue();
}
}
//代码此时有问题 我虽然实现了 栈A入元素, 栈B出元素 且用另外一个队列保存
//但是没有领会到问题所在 两个栈实现队列的功能即可!!!!
//所以此处无需构造队列的实际结点
//栈的结点结构
class NodeStack{
Object data;//元素
NodeStack next;//相当于指针 指向下一个
public NodeStack(){
}
public NodeStack(Object data) {
this.data = data;
//this.next = next;
}
}
class Test{
/*先实现A栈 负责 入元素*/
NodeStack top;//top一直指向顶点元素
private int sizeStack;
public Test(){
this.InitStackA();
this.InitStackB();
}
public void InitStackA(){
top=null;
this.sizeStack=0;
}
public boolean isEmptyStackA(){
return this.sizeStack==0;
}
/*对栈A进行入栈操作*/
//先插入的是栈底
//top指针始终指向栈顶,所以top紧跟最新的元素
public void pushStackA(){
NodeStack nodeAStack=new NodeStack();
System.out.println("请输入元素入A队列:");
Scanner scanner=new Scanner(System.in);
Object obj=scanner.nextLine();
nodeAStack.data=obj;
nodeAStack.next=top;
top=nodeAStack;
this.sizeStack++;
}
public Object popStackA(){
Object value;
if(isEmptyStackA()){
System.out.println("空队列");
return 0;
}
value = top.data;//因为top是指向栈顶的指针
NodeStack Oldtop=top;
top=top.next;
Oldtop=null;
--sizeStack;
return value;
}
/*实现一个栈 进行出栈操作*/
//而该栈必须要有元素 所以必须得有入栈步骤 同理 A结点 功能也要有一个出栈操作。
NodeStack topB;//top一直指向顶点元素
private int sizeStackB;
public void InitStackB(){
topB=null;
this.sizeStackB=0;
}
public boolean isEmptyStackB(){
return this.sizeStackB==0;
}
public void pushStackB(Object obj){
NodeStack nodeAStackB=new NodeStack();
//System.out.println("从栈A中开始元素入栈:");
//obj=this.popStackA();
nodeAStackB.data=obj;
nodeAStackB.next=topB;
topB=nodeAStackB;
sizeStackB++;
}
public Object popStackB(){
Object value;
if(isEmptyStackB()){
System.out.println("空B栈");
return 0;
}
value = topB.data;//因为top是指向栈顶的指针
NodeStack Oldtop=topB;
topB=topB.next;
Oldtop=null;
sizeStackB--;
return value;
}
//利用栈 实现队列的功能
//但是这里存在一个问题 如果B栈原本有元素呢
//那就先使其出栈
public void EnQueuebyStacks(){
if(this.isEmptyStackB()){
for (int i = 0; i < this.sizeStackB; i++) {
this.DeQueue();
}
}
System.out.println("请输入元素的个数n:");
Scanner scanner=new Scanner(System.in);
int num=scanner.nextInt();
for (int i = 0; i < num; i++) {
this.pushStackA();
this.pushStackB(this.popStackA());
}
}
public void DeQueue(){//出队
int numsize=this.sizeStackB;
for (int i = 0; i <numsize ; i++) {
System.out.println("出队列元素为:"+this.popStackB());
}
}
}
队列:先进先出
栈:先进后出
要求:两个队列q1 q2
利用两个队列实现压栈:
直接入队q1就行 这入元素都一样
利用两个队列实现弹/出栈:
情况1:如果队列q1存在元素,则将q1中n-1个元素排入q2中,剩余一个直接弹出
情况2:q1不存在元素,而q2经过之前操作从q1转移了元素,即现在所有元素都在q2中,那么也是将q2中n-1个元素全部排入q1中,剩余一个直接弹出
这样就实现了先进后出的弹栈操作。
同时要注意到 如果出栈时,A队列 B 队列都只有一个元素 ,那么无需转移
import com.sun.corba.se.spi.ior.ObjectKey;
import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;
import java.util.Scanner;
public class TwoQueueAStack {
public static void main(String[] args) {
queueNodeLink q=new queueNodeLink();
//入栈
Scanner scanner=new Scanner(System.in);
Object obj=0;
System.out.println("******输入需要入栈个数******");
int num=scanner.nextInt();
Scanner scanner2=new Scanner(System.in);
for (int i=0;i<num;i++){
System.out.println("****请输入入栈元素:****");
obj=scanner2.nextLine();
//System.out.println(obj);
q.EnQueueA(obj);
}
//出栈
q.QueuetoStackEnqueue();
//q.QueuetoStackEnqueue();
q.EnQueueA("adsad");
q.QueuetoStackEnqueue();
q.QueuetoStackEnqueue();
q.QueuetoStackEnqueue();
q.QueuetoStackEnqueue();
q.QueuetoStackEnqueue();
q.QueuetoStackEnqueue();
}
}
class Node{
Object element;
Node head;//这个用于指向有元素的的第一个结点
Node tail;//指向尾结点
//Node next;
public Node(Object element) {
this.element = element;
}
public Node() {
}
}
class queueNodeLink{
Node node;
Object data;
int size=0;
public queueNodeLink(){
}
//初始化A结点 生成一个头结点
public void InitQueueA(Object obj){
node=new Node();
node.head=null;
node.tail=null;
node.element=obj;
this.size++;
}
//栈入队,无论队列A 和队列B怎样都是直接A对入队 认为压栈。
public void EnQueueA(Object obj){
if(node==null){
this.InitQueueA(obj);
}
else{
Node n=new Node();//创造一个新的结点
n.element=obj;
Node tem=node;//我要找到null的上一个结点
while(tem.tail!=null){
tem=tem.tail;
}
tem.tail=n;
n.head=tem;
n.tail=null;
this.size++;
}
}
//A队出队
public Object DeQueueA(){
Node temnode=null;
Object value=null;
value=node.element;//获取元素
temnode=node;//存储当前结点
node=node.tail;//指向下一个
temnode=null;//释放该结点
size--;
return value;
}
public boolean isEmptyA(){
return this.size==0;
}
/*********开始构造队列B************/
Node nodeB;
Object dataB;
int sizeB=0;
public boolean isEmptyB(){
return this.sizeB==0;
}
//初始化队列B 生成一个头结点
public void InitQueueB(Object obj){
nodeB=new Node();
nodeB.head=null;
nodeB.tail=null;
nodeB.element=obj;
this.sizeB++;
}
//B 队列入列 通过队列A转移 每次转移n-1个
public void EnQueueStack(){
while(nodeB==null){
Object obj=null;
obj=this.DeQueueA();
this.InitQueueB(obj);
}
Object obj=null;
int num=this.size-1;
for (int i = 0; i <num; i++) {//每次转移n-1个
Node nB=new Node();//创造一个新的结点
obj=this.DeQueueA();
nB.element=obj;
Node tem=nodeB;//我要找到null的上一个结点
while(tem.tail!=null){
tem=tem.tail;
}
//当tem.tail为空时
tem.tail=nB;
nB.head=tem;
nB.tail=null;
this.sizeB++;
}
}
//B队列出队
public Object DeQueueB(){
Node temnode=null;
Object value=null;
value=nodeB.element;//获取元素
temnode=nodeB;//存储当前结点
nodeB=nodeB.tail;//指向下一个
temnode=null;//释放该结点
sizeB--;
return value;
}
//出栈、
//还要考虑 A中只有一个元素的时候
public Object QueuetoStackEnqueue(){
if(!this.isEmptyA()){//A 不为空时
if(this.size!=1){
this.EnQueueStack();//转移n-1个元素到B中
Object obj=this.DeQueueA();
System.out.println("出栈元素:"+obj);
return obj;
}else{
Object obj=this.DeQueueA();
System.out.println("出栈元素:"+obj);
return obj;
}
}else if(!this.isEmptyB())//A空 B不空时 转移
{
if(this.size!=1){
int num=this.sizeB-1;
for (int i = 0; i <num ; i++) {
Object obj=this.DeQueueB();//B 队出元素
this.EnQueueA(obj);//入A队
}
Object value=this.DeQueueB();//排出最后一个
System.out.println("出栈元素:"+value);
return value;
}else{
Object value=this.DeQueueB();//排出最后一个
System.out.println("出栈元素:"+value);
return value;
}
}else{
System.out.println("全空 无法弹栈");
return null;
}
}
}
后面四个参考博文
因为栈是先进后出
而在十进制、八进制的转化过程中,是倒着排过来的
//十进制 转换为八进制 同理可用
public void BaseConversion(){
System.out.println("请输入需要转化的十进制数*****");
Scanner scanner=new Scanner(System.in);
int convsrsion=scanner.nextInt();
while(convsrsion!=0){
this.push(convsrsion%8);
convsrsion/=8;
}
System.out.print("十进制转八进制:");
while(!this.isEmpty()){
System.out.print(this.pop());
}
}
刚刚开始做的时候,按照常规的发现在括号比较那 出现问题
一直无法解决
原因只能发现我设定的Object类中没有char方法,而且无法强制转化
看了博客其他人是在类的定义的时候加了一个
好像涉及泛型
目前的知识盲区 后面肯定可理解
因为我前面的参数和返回类型都是Object类,而char属于八种基本类型,所以这需要自动装箱,char的父类Object是Character
另外这个是泛类型 参考一下 Java_泛型的作用
以下是解决办法。
方法1:
pop返回类型为Object,而我输入的是字符串转了一次为字符类型
而后面对比的时候字符串 虽然保存为字符,但是pop保存的类型为Object,就把它强制转换为String,所以做对比的时候做一个取舍 那一步要都是一个类型
这样就可以解决!
参考Java中char和String的相互转换
方法2:泛类型
import java.util.Scanner;
public class matchStack {
public static void main(String[] args) {
StackNodematch stack=new StackNodematch();
System.out.println(stack.match());
}
}
class StackNodematch<Item>{
private class Node{
Item item;
Node next;
public Node(Item item) {
this.item = item;
}
@Override
public String toString() {
return "Node{" +
"item=" + item +
'}';
}
}
private Node top;
private int size=0;
public StackNodematch() {
this.InitStack();
}
private void InitStack(){
this.size=0;
this.top=null;
}
public boolean isEmpty(){
return this.size==0;
}
public void push(Item item){
Node node=new Node(item);
node.next=top;
top=node;
size++;
}
public Item pop(){
Item value;
if(isEmpty()){
System.out.println("空栈");
return null;
}
value = top.item;//因为top是指向栈顶的指针
Node Oldtop=top;
top=top.next;
Oldtop=null;
size--;
return value;
}
@Override
public String toString() {
return "StackNodematch{" +
"top=" + top +
'}';
}
public boolean match(){
StackNodematch<Character> s=new StackNodematch<>();
System.out.println("请输入需要检测的括号:");
String kuohao;
Scanner scanner=new Scanner(System.in);
kuohao=scanner.nextLine();
char[] c=kuohao.toCharArray();
for (int i=0;i<kuohao.length();i++){
System.out.println("此时的字符括号:****"+c[i]);
switch (c[i]){
case ')':
//String x=String.valueOf('(');
//System.out.println(this.pop());
if(!s.isEmpty()&&s.pop()=='('){//看了一下 Object里没有char的
break;
}else {
System.out.println("第"+(i+1)+"个元素括号不匹配--->"+c[i]);
return false;
}
case ']':
if(!s.isEmpty()&&s.pop()=='['){
break;
}else {
System.out.println("第"+(i+1)+"个元素括号不匹配--->"+c[i]);
return false;
}
case '}':
if(!s.isEmpty()&&s.pop()=='{'){
break;
}else {
System.out.println("第"+(i+1)+"个元素括号不匹配--->"+c[i]);
return false;
}
default:
s.push(c[i]);
if((i)%2==0&&(i+1)==kuohao.length()){
System.out.println("第"+(i+1)+"个少对应的括号!");
return false;
}
break;
}
}
return this.isEmpty();
}
}
更新中
更新中 即逆波兰表达式