栈的存储结构

来源:互联网 发布:java类适配器 编辑:程序博客网 时间:2024/06/09 11:10

一、栈的概念

  • 栈是一种只允许在一端进行插入和删除的线性表,它是一种操作受限的线性表。
  • 在表中只允许进行插入和删除的一端称为栈顶(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)顺序表可按元素位序随机存取结点。
  • 顺序表的缺点如下
  • 做插入、删除操作时,须大量地移动数据元素,效率比较低。
  • 要占用连续的存储空间,存储分配只能预先进行。如果估计量过大,可能导致后面的大量空间闲置;如果预先分配过小,又会造成数据溢出。
  • 链表和顺序表的优缺点刚好相反。
  • -
原创粉丝点击