【数据结构与算法基础】栈、队列存储、单链表实现

一、栈存储

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
代码实现:

/**
 * @Author: Stephen
 * @Date: 2019/12/17 22:47
 * @Content: 实现栈存储
 */
public class Mystack {
    /**
     * 实现方式:
     *      底层使用数组 压入元素 在数组最后一位添加数据
     *      取出栈点元素
     */

    // 栈的底层使用数组存储数据
    Object[] elements;

    public Mystack(){
        elements = new Objects[0];
    }

    // 压入元素
    public void push(Objects element){
        Object[] newarr = new Object[elements.length+1];
        for (int i=0;i<elements.length;i++){
            newarr[i] = elements[i];
        }
        newarr[elements.length] = element;
        elements = newarr;
    }

    // 取出栈顶元素
    public Object pop(){
        if (elements.length==0){
            throw new RuntimeException("栈为空");
        }
        // 去除数组的最后一个元素
        Object element = elements[elements.length-1];
        // 创建一个新的数组
        Object[] newArr = new Object[elements.length-1];
        // 原数组中除了最后一个元素的其它元素都放入到新数组中
        for (int i=0;i<elements.length-1;i++){
            newArr[i] = elements[i];
        }
        // 替换数组
        elements = newArr;
        // 返回栈顶元素
        return element;
    }

    // 查看栈顶元素

    public Object peek() {
        return elements[elements.length-1];
    }

    // 判断栈是否为空
    public boolean isEmpty(){
        return elements.length==0;
    }
}

二、队列存储

定义:队列,又称为伫列(queue),是先进先出(FIFO, First-In-First-Out)的线性表。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。

和堆栈一样的,也有两种操作,进队(EnQueue)和出队(DeQueue),对于空队列进行出队操作会造成下溢出(underflow),相应的堆满队列进行进队操作为发生上溢出
代码实现

/**
 * @Author: Stephen
 * @Date: 2019/12/17 23:17
 * @Content: 实现队列
 */
public class MyQueue {
    Object[] elements;

    public MyQueue(){
        elements = new Objects[0];
    }

    /**
     * 入队
     * @param element
     */
    public void add(Object element){
        Object[] newarr = new Object[elements.length+1];
        for (int i=0;i<elements.length;i++){
            newarr[i] = elements[i];
        }
        newarr[elements.length] = element;
        elements = newarr;
    }

    /**
     * 出队 : 将对头的取出
     */
    public Object poll(){
        if (elements.length==0){
            throw new RuntimeException("队列为空");
        }
        // 把数组中的第0个元素取出
        Object element = elements[0];
        Object[] newArr = new Object[elements.length-1];
        for (int i=0;i<newArr.length;i++){
            newArr[i] = elements[i+1];
        }
        // 替换数组
        elements = newArr;
        return element;
    }

    public boolean isEmpty(){
        return elements.length==0;
    }
}

三、单链表存储

单链表是链表的其中一种基本结构。一个最简单的结点结构如图所示,它是构成单链表的基本结点结构。在结点中数据域用来存储数据元素,指针域用于指向下一个具有相同结构的结点。
因为只有一个指针结点,称为单链表。
在这里插入图片描述
单链表中三个概念需要区分清楚:分别是头指针,头节点和首元节点。

  • 头结点:有时,在链表的第一个结点之前会额外增设一个结点,结点的数据域一般不存放数据(有些情况下也可以存放链表的长度等信息),此结点被称为头结点。
    若头结点的指针域为空(NULL),表明链表是空表。头结点对于链表来说,不是必须的,在处理某些问题时,给链表添加头结点会使问题变得简单。
    首元结点:链表中第一个元素所在的结点,它是头结点后边的第一个结点。

  • 头指针:永远指向链表中第一个结点的位置(如果链表有头结点,头指针指向头结点;否则,头指针指向首元结点)。

  • 头结点和头指针的区别:头指针是一个指针,头指针指向链表的头结点或者首元结点;头结点是一个实际存在的结点,它包含有数据域和指针域。两者在程序中的直接体现就是:头指针只声明而没有分配存储空间,头结点进行了声明并分配了一个结点的实际物理内存。
    在这里插入图片描述

单链表中可以没有头结点,但是不能没有头指针!
头节点的引入能使链表对第一个元素的删除和插入和其他元素相同,不用另外说明,使得代码更加简洁。
代码实现

/**
 * @Author: Stephen
 * @Date: 2019/12/17 23:45
 * @Content: 单链表的实现
 */
public class Node {
    // 节点内容
    Object data;
    // 下一个节点
    Node next;

    public Node(Object data){
        this.data = data;
    }

    // 为节点追加节点
    public Node append(Node node){
        // 想要在一个节点无线追加
        // 判断当前节点是否有元素
        Node currentNode = this;
        // 循环向后找
        while (true){
            // 通过当前节点找到下一个节点
            Node nextNode = currentNode.next;
            // 如果下一个节点为空 则表示最后一个节点
            if (nextNode == null){
                // 当前节点为最后一个节点
                break;
            }
            // 赋给当前节点
            currentNode = nextNode;
        }
        // 把需要追加的节点追加为找到当前节点的下一个节点
        currentNode.next = node;
        return this;
    }
    // 获取下一个节点
    public Node next(){
        return this.next;
    }
    // 获取节点中的数据
    public Object getData(){
        return this.data;
    }

    // 判断当前节点是否是最后一个节点
    public boolean isLast(){
        return next==null;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值