数组&链表【Java算法(二)】

写在前面的话:

本章内容代码占主要(且经过编译运行)

  • IDE:IntelliJ IDEA 2021.2.1
  • JDK:Java8

目录

1.数组

1.1 通过数组下标查询数组内容

1.2 更新数组(改变数组当中的一些值)

1.3 对数组进行增加与删除 

2.链表 


项目架构:

1.数组

1.1 通过数组下标查询数组内容

Search.java

/*
    数组查询:通过下标即可
    时间复杂度: O(1)
    空间复杂度: 根据定义的数组长度,成正比
 */

public class Search {

    public static void main(String[] args) {

        int[] array = new int[]{0,1,2,3,4,5,6,7,8,9};

        //通过下标,找到对应的数值
        System.out.println(array[0]);//找数组的第一个数
    }
}

1.2 更新数组(改变数组当中的一些值)

UpdateArray.java

/*
    更新数组:通过下标来查找数组,并对其进行赋值
 */

public class UpdateArray {

    public static void main(String[] args) {

        int[] array = new int[]{0,1,2,3,4,5,6,7,8,9};

        //对数组进行遍历
        System.out.print("数组更新前:[");
        for(int i:array){
            System.out.print(i);
            if(i != array.length - 1){
                System.out.print(",");
            }
        }
        System.out.println("]");

        //对数组进行更新
        array[0] = 100;//将数组的第1个数进行修改,值为100

        //对数组进行遍历
        System.out.print("数组更新后:[");
        for(int i:array){
            System.out.print(i);
            if(i != array.length - 1){
                System.out.print(",");
            }
        }
        System.out.println("]");
    }
}

1.3 对数组进行增加与删除 

Array.java

该类可以单独拿出来,添加了泛型

/*
    数组类(加入泛型)
 */

import java.util.AbstractList;

public class Array<E>{

    private static final long serialVersionUID = 1234543876543654L;

    private E[] array;
    private int size;//数组中存储的元素个数

    /**
     * 创建Array类的实例
     */
    public Array(){
        array = (E[]) new Object[10];//未指定时,存储空间为10
    }

    /**
     * 创建Array类的实例,并指定存储空间大小
     * @param capacity int 存储空间大小
     */
    public Array(int capacity){
        if(capacity > 0){
            //创建一个存储空间为size的数组
            array = (E[]) new Object[capacity];
        }else if(capacity == 0){
            array = (E[]) new Object[]{};
        }else{
            //手动抛出异常,参数size非法
            throw new IllegalArgumentException("参数size的值小于0!参数size的值:" + capacity);
        }
    }

    //设置数组(扩容时需要将地址赋值给属性)
    public void setArray(E[] array){
        this.array = array;
    }

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

    //获取数组长度
    public int getArrayLength(){
        return array.length;
    }

    /**
     * 数组的中间插入、超范围插入(扩容)
     * @param index    插入的位置
     * @param element  插入的元素
     */
    public void insert(int index , E element){

        //判断数组是否需要扩容
        if(size >= array.length){
            expandCapacity(size);
        }

        //判断index是否超出数组范围
        if(index < 0 || index > size){//index == size时,相当于尾部插入
            throw new IllegalArgumentException("参数index不符合范围!参数index的值:" + index);
        }

        //在数组下标index以及之后的元素依次往后移一位
        for(int i = size - 1;i >= index;i--){
            array[i + 1] = array[i];//元素往后移
        }

        //将元素插入数组下标index处  ==> 数组更新操作
        array[index] = element;

        //插入后,元素个数增加,size加1
        size++;
    }

    /**
     * 插入元素,直接在尾部添加
     * @param element 插入的元素
     */
    public void insert(E element){

        //判断数组是否需要扩容,同样需要判断(数组可能无剩余空间,需扩容)
        if(size >= array.length){
            expandCapacity(size);
        }

        array[size] = element;//在数组尾部插入数据

        //插入后,元素个数增加,size加1
        size++;

    }

    /**
     * 对数组进行扩容
     * @param size  数组中元素个数
     */
    public void expandCapacity(int size){

        //扩容成原来的数组的两倍
        E[] newArray = (E[]) new Object[array.length * 2];

        //将原来数组中的元素全部复制到新数组当中
        if (size >= 0) System.arraycopy(array, 0, newArray, 0, size);

        //将扩容后的数组的首地址赋值给array(该类的属性)
        setArray(newArray);

    }

    /**
     * 删除数组当中的元素
     * @param index 删除元素的数组下标
     */
    public void deleteElement(int index){
        //判断index是否超出数组范围
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("参数index不符合范围!无法删除该index位置的值:" + index);
        }

        for(int i = index;i < size - 1;i++){
            array[i] = array[i+1];
        }

        //删除元素后,size减一
        size--;
    }

    @Override
    public String toString() {
        String str = "[";
        //只遍历数组当中的元素个数
        for(int i = 0;i < size;i++){
            str += array[i];
            //当不是最后1个元素,需要加逗号
            if(i != size - 1){
                str += ",";
            }
        }
        //最后加一个"]"结尾
        str += "]";
        return str;
    }
}

Add.java 

用来对Array.java测试用的

/*
    对数组进行增加数据
    1.中间插入
    2.尾部插入
    3.超范围插入(涉及到扩容问题)
 */

import java.util.ArrayList;

public class TestArray {

    public static void main(String[] args) {
        Array<String> array = new Array<>(3);
        array.insert("张三");
        array.insert("李四");
        array.insert("王五");
        array.insert("钱六");
        System.out.println(array);
        Array<Integer> array1 = new Array<>(5);
        array1.insert(1);
        array1.insert(2);
        array1.insert(3);
        array1.insert(4);
        System.out.println(array1);
    }

    public void test1(){
        ArrayList<Integer> arrayList = new ArrayList<>();
    }

    public void test2(){
        Array array = new Array(3);
        array.insert(0,1);
        System.out.println(array);
        array.insert(1,2);
        System.out.println(array);
        array.insert(3);
        System.out.println(array);
        array.insert(3,4);
        System.out.println(array);
        System.out.println("删除第2个元素[数组坐标:1]:");
        array.deleteElement(1);
        System.out.println(array);
        System.out.println("增加元素:");
        array.insert(5);
        System.out.println(array);
    }
}

2.链表 

链表都放在一个类中,可以直接使用。

LinkedList.java

该类中没有包含主方法(main)

/*
    链表
 */

public class LinkedList {

    //创建一个节点
    private class Node{
        int data;//数据
        Node next;//下一个节点

        //构造器
        Node(int data){
            this.data = data;
        }
    }

    private Node head;//头结点
    private Node tail;//尾部节点
    private int size;//链表中的元素个数

    /**
     * 插入
     * @param index    插入的位置
     * @param element  插入的元素
     */
    public void insert(int index,int element){

        //判断index是否超出数组范围
        if(index < 0 || index > size){//index == size时,相当于尾部插入
            throw new IllegalArgumentException("参数index不符合范围!参数index的值:" + index);
        }

        Node insertedNode = new Node(element);//创建一个节点,方便插入到链表当中

        if(index == 0){
            //插入的位置是头结点
            insertedNode.next = head;//”插入节点”的下一个节点 ——> 原先的头结点
            head = insertedNode;//将该节点设置为”头结点”
        }else if(index == size){
            //插入的位置是尾部
            Node preNode = get(index - 1);//找打前一个节点
            preNode.next = insertedNode;//将"要插入的节点"插入到链表当中
            tail = insertedNode;//并将该节点设置成尾部节点
        }else{
            //这里属于中间插入的部分
            Node preNode = get(index - 1);//找到前一个节点
            Node nextNode = preNode.next;//这里只需要1个next(因为insertedNode还没有插入进来)

            //将"要插入的节点"插入链表当中
            preNode.next = insertedNode;//将"原先的前一个节点"的后1个节点 ——> "要插入的节点"
            insertedNode.next = nextNode;

        }

        size++;//插入后,元素个数加1
    }

    /**
     * 删除链表中的节点
     * @param index
     */
    public void deleteElement(int index){
        //判断index是否超出数组范围
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("参数index不符合范围!无法删除参数index的值:" + index);
        }

        if(index == 0){
            //删除头结点
            if(size == 1){//判断该链表是否只有1个元素
                //如果只有1个元素,删除即可
                size = 0;//设置为0,元素个数为0
            }
            //如果元素个数大于1
            Node node = head.next;//找到当前头结点的下一个节点
            head = node;//将该节点设置成头结点
        }else if(index == size - 1){//链表的尾部节点
            Node node = get(index - 1);//找到尾部节点的前一个节点
            node.next = null;//将node节点的下一个节点设置为空
            tail = node;//将该节点设置成尾部节点
        }else{
            //要删除的节点在中间
            Node preNode = get(index - 1);//找到前一个节点
            Node nextNode = get(index).next;
            preNode.next = nextNode;
        }
        size--;//删除后,元素个数减一
    }

    /**
     * 查询链表当中的节点
     * @param index  查询节点的下标
     * @return
     */
    public Node get(int index){

        //判断index是否超出数组范围
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("参数index不符合范围!参数index的值:" + index);
        }

        Node SearchNode = head;//要查询的节点

        //从头结点开始遍历
        for (int i = 0;i < index;i++){ //时间复杂度:O(n)
            SearchNode = SearchNode.next;//一直找到要SearchNode前一个节点  (故i < index)
        }

        return SearchNode;//返回查询的节点

    }

    public void printList(){

        Node node = head;

        for(int i = 0;i < size;i++){
            System.out.println(node.data);
            node = node.next;//打印下一个节点
        }
    }
}
TestList.java

用来测试LinkedList.java文件

/*
    测试链表
 */

public class TestList {

    public static void main(String[] args) {

        LinkedList list = new LinkedList();
        list.insert(0,1);
        list.insert(1,2);
        list.insert(2,3);
        list.insert(3,4);
        list.insert(4,5);
        list.insert(5,6);
        list.insert(6,7);
        list.printList();
        System.out.println("删除链表中的节点:");
        list.deleteElement(3);//元素:4
        list.printList();
        System.out.println("删除链表中的节点:");
        list.deleteElement(3);//元素:5
        list.printList();

    }
}

视频地址:点击链接,观看视频​​​​​​​ 

posted @ 2022-03-31 14:02  辰梦starDream  阅读(1)  评论(0编辑  收藏  举报  来源