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