栈的存储结构

一、栈的概念

  • 栈是一种只允许在一端进行插入和删除的线性表,它是一种操作受限的线性表。
  • 在表中只允许进行插入和删除的一端称为栈顶(top)。另一端称为栈底(bottom)。
  • 栈的插入操作称为入栈或者进栈(push)。栈的删除操作称为出栈或者退栈(pop)。
  • 当栈中无数据时,我们称为空栈。
  • 栈的特点:先进后出。!
    这里写图片描述
    二、栈的顺序存储结构

java实现代码

class SqStack{
    private int []stack;//定义栈
    private int top;//栈顶
    //初始化栈
    public SqStack(){
    this.stack=new int[10];
    this.top=0;
    }
    public SqStack(int size){
        this.stack=new int[size];
        this.top=0;
    }
    //入栈,首先先判断是否满,如果满了,扩容!然后赋值。
    public void push(int val){
        if(full())
        resize();
        this.stack[this.top++]=val;
    }
    //出栈,首先先判断是否空,如果空,直接return!
    public void pop(){
        if(empty())
        return;
        this.top--; 
    }
    //栈顶
    public int top(){
        return this.stack[this.top-1];
    }
    //判空
    public boolean empty(){
         return this.top == 0;
    }
    //判满
    public boolean full(){
        return this.top==this.stack.length;
    }
    //栈的扩容,一次扩容2倍
    public void resize(){
    this.stack=Arrays.copyOf(this.stack,this.stack.length*2);
    }
    }

//main实现代码测试

public class TestStackDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        SqStack s1= new SqStack();
        for (int i=0; i<20; i++ ){
        s1.push((int)(Math.random()*100));
        }
        while(!s1.empty()){
            System.out.printf("%d ",s1.top()); 
            s1.pop();
        }   
     }      
}
  • 注意:
  • 对于顺序栈,入栈时,首先判断是否满了,栈满的条件是top==stack.length;满了就要想办法扩容。
  • 出栈和读栈顶元素操作时,先判断是否为空,为空时不能操作,否则会产生错。

三、栈的链式存储结构
- 为避免栈上溢,更好的办法是使用链式存储结构,让多个栈共享所有可用存储空间。所以,栈也可以采用链式存储结构表示,这种结构的栈简称为链栈。

java实现代码

//首先定义一个节点
class Node{
    int value;
    Node next;
    Node(){
    this(0);
    }
    //对节点初始化
    Node(int value){
    this.value= value;
     this.next = null;
    }
}
//定义一个链栈
class LinkStack{
    Node bottom;//栈底
    Node top;//栈顶
    //对栈底和栈顶初始化
    public LinkStack(){
    top=bottom = new Node(0);
    }
    //入栈操作,还是先定义一个节点,然后头节点更新一下。
    public void push(int val){
    Node node = new Node(val);
    node.next=this.top;
    this.top=node;
    }
    //出栈操作,判断头结点是否为空,否则更新头结点
    public void pop(){
        if(this.top == null){
            return;
        }
        else{
        this.top=this.top.next;
        }           
    }
    //栈顶就是top节点的值
    public int top(){
        return this.top.value;
    }
    //判空
    public boolean empty(){
        return this.top==this.bottom;
    }
    //自己设计toString()
    public String toString(){
        StringBuilder bulider =  new StringBuilder();
        Node node = this.top;
        while(node != bottom){
            bulider.append(node.value + " ");
            node = node.next;
        }
        return bulider.toString();
    }

函数的实现

public class TestLinkStackDemo {
    public static void main(String[] args) {
        LinkStack q1 = new LinkStack();
        for (int i=0; i<20; i++ ){
            q1.push((int)(Math.random()*100));
        }
        System.out.println(q1.toString());
    }

}

三、单链表
Java代码

//创节点
class Node{
    int value;
    Node next;
    Node(){
        this(0);
    }
    //初始化节点
    Node(int value){
    this.value= value;
     this.next = null;
    }
}
//创单链表
class LinkList{
    Node head;
    public LinkList(){
    this.head = new Node();
    }
    public boolean empty(){
    return head==null;
    }
    //头插直接新建一个结点,然后更新头结点
    public void insertHead(int value){
       Node node = new Node(value);  
       node. next = head;  
        head = node;
    }
    //尾插,先将头结点给一个临时结点,然后临时结点跑到尾,然后新建结点
    public void insertTail(int value){
        Node ptail = head;
        while(ptail.next != null){
            ptail = ptail.next;
        }
        ptail.next = new Node(value);

    }
    //删除节点
    public void destroy(int value){
            Node pcur = head.next;
            Node ppre = head;
            while(pcur != null){
                if(pcur.value == value){
                    ppre.next = pcur.next;
                    break;
                }
                ppre = pcur;
                pcur = pcur.next;
        }

    }
    public String toString(){
        StringBuilder builder=new StringBuilder();
        Node n=head;
        while(n!=null){
            builder.append(n.value+"");
            n=n.next;
        }
        return builder.toString();
    }

}

main测试代码

public class TestLinkListDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LinkList q1 = new LinkList();
        for (int i=0; i<20; i++ ){
            q1.insertHead((int)(Math.random()*100));
        }
        System.out.println(q1.toString());      
    }
}

四、顺序表和链表的比较

  • 顺序表的优点如下
  • (1)用数组存储数组元素,操作方法简单,容易实现。
  • (2)无须为表示结点间的逻辑关系而增加额外的存储开销。
  • (3)存储密度高。
  • (4)顺序表可按元素位序随机存取结点。
  • 顺序表的缺点如下
  • 做插入、删除操作时,须大量地移动数据元素,效率比较低。
  • 要占用连续的存储空间,存储分配只能预先进行。如果估计量过大,可能导致后面的大量空间闲置;如果预先分配过小,又会造成数据溢出。
  • 链表和顺序表的优缺点刚好相反。
  • -
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值