栈
栈
栈(stack)是一个先入后出的有序列表;其元素的插入和删除只能从一端进行操作,我们将其称之为栈顶(Top),另一端我们称之为栈底(Bottom)。
栈的应用场景
- 子程序的调用:在跳往子程序之前,将下个指令的地址存到堆栈中,子程序结束执行将地址取出,回到原来的程序中。
- 处理递归调用:和子程序调用类似,除了存储下一个指令地址以外,将参数、区域变量等数据也存入堆栈中。
- 表达式转换:中缀表达式转后缀表达式以及表达式求值。
- 二叉树的遍历
- 图形的深度优先搜索法。
利用数组模拟栈
分析思路
定义数组变量用来存储数组,模拟栈 ;
定义指针变量top,初始化为-1;
入栈的操作,当有数据加入到栈时,top++;stack[top]=data;
出栈操作,int value=stack[top];top--;return value;
//代码演示
class Stack{
public int[] stack;
public int maxsize;
public int top=-1;
//构造方法
public Stack() {
}
public Stack(int maxsize) {
this.maxsize = maxsize;
stack=new int[this.maxsize];
}
//栈满
public boolean isfull(){
return top==maxsize-1;
}
//栈空
public boolean isEmpty(){
return top==-1;
}
//入栈
public void push(int num){
if(isfull()){
System.out.println("栈满");
return;
}
top++;
stack[top]=num;
}
//出栈
public int pop(){
if(isEmpty()){
System.out.println("栈为空");
}
int value=stack[top];
top--;
return value;
}
//显示栈
public void show(){
if(isEmpty()){
System.out.println("栈空");
return;
}
//需要从栈顶开始显示数据
for(int i=top;i>=0;i--){
System.out.println(stack[i]);
}
}
}
注意:在类中定义了top;但是在方法中操作top指针的值会改变top的值。
利用链表模拟栈
分析思路
入栈:定义辅助指针完成遍历,遍历到最后,从最后添加节点;同时让top指针指向添加的这个节点
出栈:定义辅助指针完成遍历;遍历找到top的前一个节点;定义辅助变量保存top值用来做函数的返回值,最后删除top这个节点。
显示:首先需要反转整个链表,然后定义辅助指针完成遍历显示。
反转链表:定义反转的头指针Reverse,定义辅助指针完成遍历cur,定义一个用来保存当前指针的下一个指针next;遍历到一个节点,将这个节点取下放在新的链表的最前端;
//遍历原来的链表,遍历到一个节点将其取出,并放在新的链表的最前端
while (cur!=null){
//保存当前节点的下一个节点,后面要使用
next=cur.next;
//将cur的下一个节点指向新链表的最前端
cur.next=Reverse.next;
//将cur连接到新链表上
Reverse.next=cur;
//将cur后移
cur=next;
}
head.next=Reverse.next;
}
//代码实现
//用链表模拟栈
class Stack2 {
//定义一个栈顶指针
public Node top;
//定义一个头节点
Node head = new Node();
//构造方法
public Stack2() {
}
//栈为空
public boolean isempty() {
return top == null;
}
//入栈
public void push(Node N) {
//因为头指针不能动,定义一个辅助指针用来遍历
Node temp = head;
while (true) {
if (temp.next == null) {//找到链表的尾部
break;
}
temp = temp.next;
}
temp.next = N;
top = N;
}
//出栈 遍历到最后一个节点top;找到top的前一个节点;将top节点从链表删除
public Node pop() {
if (isempty()) {
System.out.println("链表为空");
}
//因为头指针不能动,定义一个辅助指针用来遍历,找到top节点的前一个节点
Node temp = head;
//定义出栈的辅助指针,因为top指针需要向前移动
Node last = top;
//遍历找到top的前一个节点
while (true) {
if (temp.next == top) {//找到了top的前一个节点
break;
}
temp = temp.next;
}
//将top节点从链表的末尾删除
temp.next = top.next;
//将top指针指向这个节点,完成指针向前移动一位
top = temp;
return last;
}
//栈的显示,栈的显示从栈顶开始显示,所以我们需要先将链表反转,接着开始遍历显示链表
public void show() {
if (head.next==null) {
System.out.println("链表为空");
return;
}
reverse(head);
Node temp = head.next;
while (true) {
if (temp == null) {//遍历到链表的最后
break;
}
System.out.println(temp.No);
temp = temp.next;
}
}
//链表反转
public void reverse(Node head) {
if(head.next==null ||head.next.next==null){
//链表为空或只有一个节点,则不需要反转
return;
}
//因为头指针不能动,定义一个辅助指针用来遍历
Node cur = head.next;
//定义一个遍历来保存当前节点的下一个节点
Node next=null;
//定义一个反转头指针
Node Reverse =new Node();
//遍历原来的链表,遍历到一个节点将其取出,并放在新的链表的最前端
while (cur!=null){
//保存当前节点的下一个节点,后面要使用
next=cur.next;
//将cur的下一个节点指向新链表的最前端
cur.next=Reverse.next;
//将cur连接到新链表上
Reverse.next=cur;
//将cur后移
cur=next;
}
head.next=Reverse.next;
}
}
//创建节点
class Node {
public int No;
public Node next;
public Node() {
}
public Node(int no) {
No = no;
}
}

浙公网安备 33010602011771号