数据结构-动态数组

本文介绍了动态数组在数据结构中的应用,详细讲解了双端栈、队列的定义及其实现,包括ArrayDoubleEndStack、ArrayQueue、ArrayLoopQueue类的设计。此外,还探讨了队列如何实现栈的功能以及双端队列ArrayDeque的特性。
摘要由CSDN通过智能技术生成

 

目录

1动态数组

1.1双端栈

 1.1.1双端栈的定义

          1.1.2ArrayDoubleEndStack类

1.2队列

         1.2.1队列的定义 

1.2.2Queue队列接口的定义 

1.2.3 ArrayQueue类

1.3队列实现栈

1.3.1QueTostack类

1.4循环队列ArrayLoopQueue 

1.4.1循环队列ArrayLoopQueue的定义

1.4.2ArrayLoopQueue类 

1.5双端队列 

1.5.1双端队列的定义 

1.5.2ArrayDeque类 


1动态数组

1.1双端栈

 1.1.1双端栈的定义

是指将一个线性表的两端当做栈底分别进行入栈和出栈操作 主要利用了栈“栈底位置不变,而栈顶位置动态变化” 的特性。

1.1.2ArrayDoubleEndStack类

package P2.线性结构;
import java.util.Iterator;
//双端栈
public class ArrayDoubleEndStack<E> implements Iterable<E> {
    //左端栈的栈顶
    private int ltop;
    //右端栈的栈顶
    private int rtop;
    //存储元素的容器
    private E[] data;
    //数组容器的默认容量
    private static int DEFAULT_CAPACITY = 10;

    public ArrayDoubleEndStack() {
        data = (E[]) new Object[DEFAULT_CAPACITY];
        ltop = -1;
        rtop = data.length;
    }

    public void pushLeft(E element) {
        if (ltop + 1 == rtop) {
            resize(data.length * 2);
        }
        data[++ltop] = element;
    }

    public void pushRight(E element) {
        if (ltop + 1 == rtop) {
            resize(data.length * 2);
        }
        data[--rtop] = element;
    }

    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        //复制左端栈的元素
        for (int i = 0; i <= ltop; i++) {
            newData[i] = data[i];
        }
        //复制右端栈的元素
        int index = rtop;
        for (int i = newLen - sizeRight(); i < newLen; i++) {
            newData[i] = data[index++];
        }
        rtop = newLen - sizeRight();
        data = newData;
    }

    public E popLeft() {
        if (isLeftEmpty()) {
            throw new IllegalArgumentException("left stack is null");
        }
        E ret = data[ltop--];
        if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY) {
            resize(data.length / 2);
        }
        return ret;
    }

    public E popRight() {
        if (isRightEmpty()) {
            throw new IllegalArgumentException("right stack is null");
        }
        E ret = data[rtop++];
        if (sizeLeft() + sizeRight() <= data.length / 4 && data.length > DEFAULT_CAPACITY) {
            resize(data.length / 2);
        }
        return ret;
    }

    public E peekLeft() {
        if (isLeftEmpty()) {
            throw new IllegalArgumentException("left stack is null");
        }
        return data[ltop];
    }

    public E peekRight() {
        if (isRightEmpty()) {
            throw new IllegalArgumentException("right stack is null");
        }
        return data[rtop];
    }

    public boolean isLeftEmpty() {
        return ltop == -1;
    }

    public boolean isRightEmpty() {
        return rtop == data.length;
    }

    public int sizeLeft() {
        return ltop + 1;
    }

    public int sizeRight() {
        return data.length - rtop;
    }

    @Override
    public String toString() {
        // 1 2 3       7 8 9
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isLeftEmpty() && isRightEmpty()) {
            sb.append(']');
            return sb.toString();
        }
        //先搞左边
        for (int i = 0; i <= ltop; i++) {
            sb.append(data[i]);
            if (i == ltop && isRightEmpty()) {
                sb.append(']');
                return sb.toString();
            } else {
                sb.append(',');
            }
        }
        //后搞右边
        for (int i = rtop; i < data.length; i++) {
            sb.append(data[i]);
            if (i == data.length - 1) {
                sb.append(']');
            } else {
                sb.append(',');
            }
        }
        return sb.toString();
    }

    @Override
    public Iterator<E> iterator() {
        return new ArrayDoubleEndStackIterator();
    }

    class ArrayDoubleEndStackIterator implements Iterator<E> {
        private ArrayList<E> list;
        private Iterator<E> it;

        public ArrayDoubleEndStackIterator() {
            list = new ArrayList<>();
            for (int i = 0; i <= ltop; i++) {
                list.add(data[i]);
            }
            for (int i = rtop; i < data.length; i++) {
                list.add(data[i]);
            }
            it = list.iterator();
        }

        @Override
        public boolean hasNext() {
            return it.hasNext();
        }

        @Override
        public E next() {
            return it.next();
        }
    }
}

1.2队列

1.2.1队列的定义 

 队列是只允许在一端进行插入操作,而在另一端进行删除操作的线性表 我们把允许删除的一端称为队首(front),插入的一端称为队尾(rear) 不含任何数据元素的队列称为空队列 队列是一种先进先出(First In Last Out)的线性表,简称FIFO 队列本身是一个线性表,其数据元素具有线性关系,只不过它是一种特殊的线性表而已 队列的插入操作,叫作入队 队列的删除操作,叫作出队

1.2.2Queue队列接口的定义 

package P1.接口;

    public interface Queue<E> extends Iterable<E> {
        public void offer(E element);   //入队
        public E poll();    //出队
        public E peek();    //查看队首元素
        public boolean isEmpty();
        public void clear();
        public int size();
    }

 

1.2.3 ArrayQueue类

package P2.线性结构;

import P1.接口.Queue;

import java.util.Iterator;

public class ArrayQueue<E> implements Queue<E> {
    private ArrayList<E> list;
    public ArrayQueue() {
        list = new ArrayList<>();
    }

    @Override
    public void offer(E element) {
        list.add(list.size(), element);
    }

    @Override
    public E poll() {
        return list.remove(0);
    }

    @Override
    public E peek() {
        return list.get(0);
    }

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

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

    @Override
    public String toString() {
        return list.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof ArrayQueue) {
            ArrayQueue other = (ArrayQueue) o;
            return list.equals(other.list);
        }
        return false;
    }
}

1.3队列实现栈

1.3.1QueTostack类

package P2.线性结构;
import P1.接口.Stack;
import java.util.Iterator;
public class QueueToStack {
    public static void main(String[] args) {
        StackImplByQueue<Integer> stack = new StackImplByQueue<>();
        System.out.println(stack);
        for (int i = 1; i <= 5; i++) {
            stack.push(i); //队列A
        }
        System.out.println(stack.toString());
        System.out.println(stack.pop());
        System.out.println(stack);  //队列B

    }
}
class StackImplByQueue<E> implements Stack<E> {
    private ArrayQueue<E> queueA;
    private ArrayQueue<E> queueB;

    public StackImplByQueue() {
        queueA = new ArrayQueue<>();
        queueB = new ArrayQueue<>();
    }

    @Override
    public int size() {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            return 0;
        } else if (!queueA.isEmpty()) {
            return queueA.size();
        } else {
            return queueB.size();
        }
    }

    @Override
    public boolean isEmpty() {
        return queueA.isEmpty() && queueB.isEmpty();
    }

    @Override
    public void push(E element) {
        if (queueA.isEmpty() && queueB.isEmpty()) {
            queueA.offer(element);
        } else if (!queueA.isEmpty()) {
            queueA.offer(element);
        } else {
            queueB.offer(element);
        }
    }

    @Override
    public E pop() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
        }
        return ret;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        E ret = null;
        if (!queueA.isEmpty()) {
            while (queueA.size() != 1) {
                queueB.offer(queueA.poll());
            }
            ret = queueA.poll();
            queueB.offer(ret);
        } else {
            while (queueB.size() != 1) {
                queueA.offer(queueB.poll());
            }
            ret = queueB.poll();
            queueA.offer(ret);
        }
        return ret;
    }

    @Override
    public void clear() {
        queueA.clear();
        queueB.clear();
    }

    @Override
    public Iterator<E> iterator() {
        if (isEmpty()) {
            return queueA.iterator();
        } else if (!queueA.isEmpty()) {
            return queueA.iterator();
        } else {
            return queueB.iterator();
        }
    }
    @Override
    public String toString() {
        if (isEmpty()) {
            return "[]";
        } else if (!queueA.isEmpty()) {
            return queueA.toString();
        } else {
            return queueB.toString();
        }
    }

}

1.4循环队列ArrayLoopQueue 

1.4.1循环队列ArrayLoopQueue的定义

该循环队列的实现思想也是动态数组 但是由于操作元素的特殊性,并不能直接由ArrayList或ArrayQueue实现 所以从头开始定义ArrayLoopQueue 

 

1.4.2ArrayLoopQueue类 

 

package P2.线性结构;

import P1.接口.Queue;
import java.util.Iterator;
//循环队列
public class ArrayLoopQueue<E> implements Queue<E> {
    private E[] data;   //存储数据的容器
    private int front;  //队首指针(实际上就是数组中的索引角标)
    private int rear;   //队尾指针
    private int size;   //元素的个数 (f < r  r-f ; r < f  r+L-f)
    private static int DEFAULT_CAPACITY = 10;   //默认容量
    public ArrayLoopQueue() {
        data = (E[]) new Object[DEFAULT_CAPACITY + 1];
        front = 0;
        rear = 0;
        size = 0;
    }
    @Override
    public void offer(E element) {
        //满了没
        if ((rear + 1) % data.length == front) {
            resize(data.length * 2 - 1);
        }
        data[rear] = element;
        rear = (rear + 1) % data.length;
        size++;
    }
    @Override
    public E poll() {
        //空不空
        if (isEmpty()) {
            throw new IllegalArgumentException("queue is null");
        }
        E ret = data[front];
        front = (front + 1) % data.length;
        size--;
        if (size <= (data.length - 1) / 4 && data.length - 1 > DEFAULT_CAPACITY) {
            resize(data.length / 2 + 1);
        }
        return ret;
    }

    @Override
    public E peek() {
        return null;
    }

    private void resize(int newLen) {
        E[] newData = (E[]) new Object[newLen];
        int index = 0;
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            newData[index++] = data[i];
        }
        data = newData;
        front = 0;
        rear = index;
    }

    @Override
    public boolean isEmpty() {
        return front == rear;
    }

    @Override
    public void clear() {
        data = (E[]) new Object[DEFAULT_CAPACITY];
        size = 0;
        front = 0;
        rear = 0;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (isEmpty()) {
            sb.append(']');
            return sb.toString();
        }
        for (int i = front; i != rear; i = (i + 1) % data.length) {
            sb.append(data[i]);
            if ((i + 1) % data.length == rear) {
                sb.append(']');
            } else {
                sb.append(',');
                sb.append(' ');
            }
        }
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof ArrayLoopQueue) {
            ArrayLoopQueue<E> other = (ArrayLoopQueue<E>) o;
            if (size != other.size) {
                return false;
            }
            int i = front;
            int j = other.front;
            while (i != rear) {
                if (!data[i].equals(other.data[j])) {
                    return false;
                }
                i = (i + 1) % data.length;
                j = (j + 1) % other.data.length;
            }
            return true;
        }
        return false;
    }

    @Override
    public Iterator<E> iterator() {
        return new ArrayLoopQueueIterator();
    }

    class ArrayLoopQueueIterator implements Iterator<E> {
        private int cur = front;

        @Override
        public boolean hasNext() {
            return cur != rear;
        }

        @Override
        public E next() {
            E ret = data[cur];
            cur = (cur + 1) % data.length;
            return ret;
        }
    }
}

1.5双端队列 

1.5.1双端队列的定义 

双端队列(double ended queue ,deque) 是限定插入和删除操作在表的两端进行的线性表 是一种具有队列和栈的性质的数据结构 

1.5.2ArrayDeque类 

package p2.线性结构;
import p1.接口.Queue;
import java.util.Iterator;

public class ArrayQueue<E> implements Queue<E> {
    private ArrayList<E> list;
    public ArrayQueue() {
        list = new ArrayList<>();
    }

    @Override
    public void offer(E element) {
        list.add(list.size(), element);
    }

    @Override
    public E poll() {
        return list.remove(0);
    }

    @Override
    public E element() {
        return list.get(0);
    }

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

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public int size() {
        return list.size();
    }

    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }

    @Override
    public String toString() {
        return list.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        if (this == o) {
            return true;
        }
        if (o instanceof ArrayQueue) {
            ArrayQueue other = (ArrayQueue) o;
            return list.equals(other.list);
        }
        return false;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值