栈结构的基本概念及操作

栈结构

什么是栈结构

栈结构是从数据的运算来分类的,也就是说栈结构具有特殊的运算规则。而从数据的逻辑结构来看,栈结构其实就是线性结构。 如果从数据的存储结构来进一步划分, 栈结构包括两类。

  • 顺序栈结构:即使用一组地址连续的内存单元依次保存栈中的数据。在程序中,可以定义一个指定大小的结构数组来作为栈,序号为0的元素就是栈底,再定义一个变量top保存栈顶的的序号即可。
  • 链式栈结构:即使用链表形式保存栈中各元素的值。链表首部(head引用所指向元素)为栈顶,链表尾部(指向地址为null)为栈底。

在这里插入图片描述
典型的栈结构,如图所示。从图中可以看出,在栈结构中只能在一端进行操作, 该操作端称为栈顶,另一端称为栈底。 也就是说,保存和取出数据都只能从栈结构的一端进行。 从数据的运算角度来分析,栈结构是按照“后进先出”(Last In First Out, LIFO) 的原则处理结点数据的。

一般栈结构的基本操作有两个:

  • 入栈(Push):将数据保存到栈项的操作。进行入栈操作前,先修改栈项引用。使其向上移一个元素位置。通过修改栈顶引用,使其向上移一个元素位置,然后将数据保存到栈顶引用所指的位置
  • 出栈(Pop):将栈顶的数据弹出的操作。通过修改栈项引用,使其指向栈中的下一个元素。
    接下来,了解如何在Java语言中建立顺序栈,并完成顺序栈结构的基本操作

1. 准备数据

class DATA3{
    String name;
    int age;
}
class StackType{
    static final int MAXLEN=50;
    DATA3[] data=new DATA3[MAXLEN+1];
    int top;
}

在类StackType中,data 为数据元素,top 为栈顶的序号。当top=0时表示栈为空,top=SIZE时表示栈满。
Java语言中数组都是从下标0开始的。在这里,为了讲述和理解的方便,从下标1开始记录据结点,下标0的位置不使用。

2.初始化栈结构

在使用顺序栈之前,首先要创建个空的顺序栈, 即初始化顺序栈。 顺序栈的初始化操作步如下:
(1)按符号常量SIZE指定的大小申请一片内存空间, 用来保存栈中的数据。
(2)设置栈项引用的值为0,表示一个空栈。

初始化顺序栈的代码示例如下:

StackType STInit() {
    StackType p;
    p = new StackType();
    if (p != null) {
        p.top = 0;
        return p;
    }
    return null;
}

3.判断空栈

判断栈是否为空,为空则不可以进行出栈操作,可以进行入栈操作

boolean STIsEmpty(StackType s){
    boolean t;
    t=(s.top==0);
    return t;
}

4.判断满栈

如果是满栈,表示该栈中没有多余的空间来保存额外的数据,此时不可进行入栈操作,但可以进行出栈操作

boolean STIsFull(StackType s) {
    boolean t;
    t = (s.top == MAXLEN);
    return t;
}

5.清空栈

void STClear(StackType s) {
    s.top = 0;
}

6.释放空间

释放空间即释放栈结构所占用的内存单元。在初始化栈结构时,使用了malloc函数分配内存空间。虽然可以使用清空栈操作,但是清空栈操作并没有释放内存空间,这里就需要使用free函数释放所分配的内存

void STFree(StackType s) {
    if (s != null) {
        s = null;
    }
}

7.入栈

入栈(Push)是栈结构的基本操作,主要操作时将数据元素保存到栈结构中。入栈操作的具体步骤如下:

1. 首先判断栈顶top,如果top大于等于SIZE,则表示溢出,进行出错处理;否则执行以下操作;
2. 设置top=top+1(栈顶引用加1,指向入栈地址);
3. 将入栈元素保存到top指向的位置;
入栈

操作示例代码:

int PushST(StackType s, DATA3 data) {
    if (s.top + 1 > MAXLEN) {
        System.out.println("栈溢出!");
        return 0;
    }
    s.data[++s.top] = data;
    return 1;
}

8.出栈

出栈(Pop)是栈结构的基本操作,主要操作域入栈相反,其操作是从栈顶弹出一个数据元素。出栈操作的具体步骤如下:

1. 首先判断栈顶top,如果top等于0,则表示为空栈,进行出错处理;否则执行以下操作;
2. 将栈顶引用top所指位置的元素返回;
3. 设置top=top-1,也就是是栈顶引用减1,指向栈的下一元素的地址,原来的栈顶元素被弹出;

出栈操作示例代码:

DATA3 PopST(StackType s) {
    if (s.top == 0) {
        System.out.println("栈为空!");
        System.exit(0);
    }
    return (s.data[s.top--]);
}

返回值是栈顶的数据元素

9.栈操作的演示实例

import java.util.Scanner;

class DATA3 {
    String name;
    int age;
}

class StackType {
    static final int MAXLEN = 50;
    DATA3[] data = new DATA3[MAXLEN + 1];
    int top;

    StackType STInit() {
        StackType p;
        p = new StackType();
        if (p != null) {
            p.top = 0;
            return p;
        }
        return null;
    }

    boolean STIsEmpty(StackType s) {
        boolean t;
        t = (s.top == 0);
        return t;
    }

    boolean STIsFull(StackType s) {
        boolean t;
        t = (s.top == MAXLEN);
        return t;
    }

    void STClear(StackType s) {
        s.top = 0;
    }

    void STFree(StackType s) {
        if (s != null) {
            s = null;
        }
    }

    int PushST(StackType s, DATA3 data) {
        if (s.top + 1 > MAXLEN) {
            System.out.println("栈溢出!");
            return 0;
        }
        s.data[++s.top] = data;
        return 1;
    }

    DATA3 PopST(StackType s) {
        if (s.top == 0) {
            System.out.println("栈为空!");
            System.exit(0);
        }
        return (s.data[s.top--]);
    }
}

public class Stack {
    public static void main(String[] args) {
        StackType st = new StackType();
        DATA3 data1 = new DATA3();
        StackType stack = st.STInit();
        Scanner input = new Scanner(System.in);
        System.out.println("入栈操作:");
        System.out.println("输入姓名 年龄进行入栈操作:");
        do {
            DATA3 data = new DATA3();
            data.name = input.next();
            if (data.name.equals("0")) {
                break;
            } else {
                data.age = input.nextInt();
                st.PushST(stack, data);
            }
        } while (true);
        String temp = "1";
        System.out.println("出栈操作:按任意非0键进行出栈操作:");
        temp = input.next();
        while (!temp.equals("0")) {
            data1 = st.PopST(stack);
            System.out.println("出栈的数据是" + data1.name + " " + data1.age);
            temp = input.next();
        }
        System.out.println("测试结束!");
        //释放栈所占用的空间
        st.STFree(st);
    }
}

代码运行实例

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值