数据结构数组、栈和队列(Java算法和数据结构总结笔记)[3/20]

数组的概念

  • 数组是有序的元素序列。若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。这些有序排列的同类数据元素的集合称为数组。
  • 数组是用于储存多个相同类型数据的集合

往数组中添加一个元素

    /**
     *
     * @param e  添加的值
     * @param index 添加元素的下标位置
     */
    public static void addElement(int e, int index){
        // 记录元素的个数
        int size = 0;
        // 创建数据
        int[] arr = new int[10];
        // 添加几个元素
        for (int i = 0; i < 5; i++) {
            arr[i] = i;
            size++;
        }
        System.out.println(arr.length);
        if (size == arr.length){
            throw new IllegalArgumentException("元素已经满了!");
        }
        if (index < 0 && index > size){
            throw new IllegalArgumentException("添加元素失败,无效索引下标!");
        }
        // 从数组的最后开始移动数据
        for (int i = size-1; i >= index; i--) {
            // 把前面一位元素,后移赋值给后一位
            arr[i+1] = arr[i];
        }
        // 位置腾出来之后,把要添加的元素赋值进去
        arr[index] = e;
        // 添加一个元素
        size++;
        // 输出结果  0 1 2 6 3 4 0 0 0 0
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }

    }

在数组中删除一个元素

    /**
     * 通过下标删除元素
     * @param index
     * @return
     */
    public static int deleteElement(int index){
        // 返回要删除的值
        int value;
        // 记录元素的个数
        int size = 0;
        // 创建数据
        int[] arr = new int[10];
        // 添加几个元素
        for (int i = 0; i < 5; i++) {
            arr[i] = i;
            size++;
        }
        if (index < 0 && index > size){
            throw new IllegalArgumentException("删除元素失败,无效索引下标!");
        }
        System.out.println();
        // 位置腾出来之后,把要添加的元素赋值进去
        value = arr[index];
        // 从数组的最后开始移动数据
        for (int i = size-1; i >= index; index++) {
            // 把前面一位元素,后移赋值给后一位
            arr[index] = arr[index+1];
        }
        size--;
        for (int i = 0; i < arr.length; i++) {
            // 输出 0,1,2,4,0,0,0,0,0,0
            if (i != arr.length - 1){
                System.out.print(arr[i] + ",");
            }else {
                System.out.print(arr[i]);
            }

        }
        // 换行
        System.out.println();
        // 返回已经删除的元素
        return value;
    }

在数组中修改一个元素

    /**
     * 通过下标修改元素
     * @param index
     * @param value
     */
    public static void updateElement(int index,int value){
        int[] arr = {1,2,3,4,5,6};
        arr[index] = value;
        for (int i = 0; i < arr.length; i++) {
            // 输出 1 2 10 4 5 6
            System.out.print(arr[i] + " ");
        }
        // 换行
        System.out.println();
    }

执行的main方法

    public static void main(String[] args) {

        /**
         * 添加元素
         */
        addElement(6,3);

        /**
         * 删除元素
         */
        deleteElement(3);

        /**
         * 修改桑元素
         */
        updateElement(2,10);
    }

什么是栈

  • 实际上就是满足后进先出(LIFO)的性质,是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除
/**
 * 栈的实现
 */
public class TestClassStack {
    // 声明数组,存放元素
    int[] arr;
    // 元素的个数
    int elementSize;
    // 栈的结构是后进先出 LIFO,栈顶为top
    int stackTop;

    public TestClassStack(int length){
        arr = new int[length];
        this.elementSize = length;
        stackTop = -1;
    }

    /**
     * 入栈
     */
    public void push(int element){
        if (stackTop > elementSize - 1)
            throw new IllegalArgumentException("Array can not add");
        ++stackTop;
        arr[stackTop] = element;
    }

    // 展示元素
    public void showElement(){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + ",");
        }
    }

    //判断栈是否为空
    public boolean isEmpty(){
        return (stackTop == -1);
    }

    /**
     * 出栈
     */
    public int pop(){
        // 拿到栈顶的元素
        int value = arr[stackTop];
        // 取出之后,元素赋值为默认值
        arr[stackTop] = 0;
        // 元素减一
        stackTop --;
        return value;
    }

    /**
     * 数组的动态扩容机制
     * @param index
     */
    private void resize(int index){
        // 创建一个新数组
        int[] newArray = new int[index];
        // 把原来数组中的值复制到新数组中
        for(int i = 0; i < elementSize; i++){  //进行赋值操作
            // 赋值
            newArray[i] = arr[i];
        }
        // 把newArray重新指向arr
        arr = newArray;
    }


    public static void main(String[] args) {
        TestClassStack testClassStack = new TestClassStack(10);
        for (int i = 0; i < 5; i++) {
            testClassStack.push(i);
        }
        testClassStack.showElement();
        System.out.println();
        while (!testClassStack.isEmpty()){
            int pop = testClassStack.pop();
            System.out.println(pop);
        }
        testClassStack.showElement();
    }

}

什么是队列

  • 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
  • 队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO)线性表。

基于数组实现一个队列:

(1)、实现一个泛型数组类

/**
 * 实现数组的元素操作
 * @param <E>
 */
public class Array<E> {

    private E[] data;
    private int size;

    // 构造函数,传入数组的容量capacity构造Array
    public Array(int capacity){
        data = (E[])new Object[capacity];
        size = 0;
    }

    // 无参数的构造函数,默认数组的容量capacity=10
    public Array(){
        this(10);
    }

    // 获取数组的容量
    public int getCapacity(){
        return data.length;
    }

    // 获取数组中的元素个数
    public int getSize(){
        return size;
    }

    // 返回数组是否为空
    public boolean isEmpty(){
        return size == 0;
    }

    // 在index索引的位置插入一个新元素e
    public void add(int index, E e){

        if(index < 0 || index > size)
            throw new IllegalArgumentException("Add failed. Require index >= 0 and index <= size.");

        if(size == data.length)
            resize(2 * data.length);

        for(int i = size - 1; i >= index ; i --)
            data[i + 1] = data[i];

        data[index] = e;

        size ++;
    }

    // 向所有元素后添加一个新元素
    public void addLast(E e){
        add(size, e);
    }

    // 在所有元素前添加一个新元素
    public void addFirst(E e){
        add(0, e);
    }

    // 获取index索引位置的元素
    public E get(int index){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Get failed. Index is illegal.");
        return data[index];
    }

    public E getLast(){
        return get(size - 1);
    }

    public E getFirst(){
        return get(0);
    }

    // 修改index索引位置的元素为e
    public void set(int index, E e){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Set failed. Index is illegal.");
        data[index] = e;
    }

    // 查找数组中是否有元素e
    public boolean contains(E e){
        for(int i = 0 ; i < size ; i ++){
            if(data[i].equals(e))
                return true;
        }
        return false;
    }

    // 查找数组中元素e所在的索引,如果不存在元素e,则返回-1
    public int find(E e){
        for(int i = 0 ; i < size ; i ++){
            if(data[i].equals(e))
                return i;
        }
        return -1;
    }

    // 从数组中删除index位置的元素, 返回删除的元素
    public E remove(int index){
        if(index < 0 || index >= size)
            throw new IllegalArgumentException("Remove failed. Index is illegal.");

        E ret = data[index];
        for(int i = index + 1 ; i < size ; i ++)
            data[i - 1] = data[i];
        size --;
        data[size] = null; // loitering objects != memory leak

        if(size == data.length / 4 && data.length / 2 != 0)
            resize(data.length / 2);
        return ret;
    }

    // 从数组中删除第一个元素, 返回删除的元素
    public E removeFirst(){
        return remove(0);
    }

    // 从数组中删除最后一个元素, 返回删除的元素
    public E removeLast(){
        return remove(size - 1);
    }

    // 从数组中删除元素e
    public void removeElement(E e){
        int index = find(e);
        if(index != -1)
            remove(index);
    }

    @Override
    public String toString(){

        StringBuilder res = new StringBuilder();
        res.append(String.format("Array: size = %d , capacity = %d\n", size, data.length));
        res.append('[');
        for(int i = 0 ; i < size ; i ++){
            res.append(data[i]);
            if(i != size - 1)
                res.append(", ");
        }
        res.append(']');
        return res.toString();
    }

    // 将数组空间的容量变成newCapacity大小
    private void resize(int newCapacity){

        E[] newData = (E[])new Object[newCapacity];
        for(int i = 0 ; i < size ; i ++)
            newData[i] = data[i];
        data = newData;
    }
}

(2)、写一个队列接口

/**
 * 队列接口
 * @param <E>
 */
public interface Queue<E> {
    int getSize();
    boolean isEmpty();
    void enqueue(E e);
    E dequeue();
    E getFront();
}

(3)、接口实现

/**
 * 实现队列
 * @param <E>
 */
public class ArrayQueue<E> implements Queue<E> {

    private Array<E> array;

    public ArrayQueue(int capacity){
        array = new Array<>(capacity);
    }

    public ArrayQueue(){
        array = new Array<>();
    }

    @Override
    public int getSize(){
        return array.getSize();
    }

    @Override
    public boolean isEmpty(){
        return array.isEmpty();
    }

    public int getCapacity(){
        return array.getCapacity();
    }

    @Override
    public void enqueue(E e){
        array.addLast(e);
    }

    @Override
    public E dequeue(){
        return array.removeFirst();
    }

    @Override
    public E getFront(){
        return array.getFirst();
    }

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Queue: ");
        res.append("front [");
        for(int i = 0 ; i < array.getSize() ; i ++){
            res.append(array.get(i));
            if(i != array.getSize() - 1)
                res.append(", ");
        }
        res.append("] tail");
        return res.toString();
    }

    public static void main(String[] args) {

        ArrayQueue<Integer> queue = new ArrayQueue<>();
        for(int i = 0 ; i < 10 ; i ++){
            queue.enqueue(i);
            System.out.println(queue);
            // 每三个元素,出栈一次
            if(i % 3 == 2){
                queue.dequeue();
                System.out.println(queue);
            }
        }
    }
}

队列输出结果

Queue: front [0] tail
Queue: front [0, 1] tail
Queue: front [0, 1, 2] tail
Queue: front [1, 2] tail
Queue: front [1, 2, 3] tail
Queue: front [1, 2, 3, 4] tail
Queue: front [1, 2, 3, 4, 5] tail
Queue: front [2, 3, 4, 5] tail
Queue: front [2, 3, 4, 5, 6] tail
Queue: front [2, 3, 4, 5, 6, 7] tail
Queue: front [2, 3, 4, 5, 6, 7, 8] tail
Queue: front [3, 4, 5, 6, 7, 8] tail
Queue: front [3, 4, 5, 6, 7, 8, 9] tail

猜你喜欢

转载自blog.csdn.net/amosjob/article/details/117414461