数据结构.数组

news2024/11/17 11:40:21

数据结构.数组

  • 1.数组的概念和特点
  • 2.数组的定义和初始化
  • 3.数组的遍历
  • 4.数组的基本操作(不多说 注解很详细)
  • 5.操作的时间复杂度

1.数组的概念和特点

数组就是一种容器(装数据的),用来存储相同类型的数据值。

数组的特点:

1.引用类型(或者可以认为数组即对象)
2.可以存同一个类型很多个数据
3.长度不可变(短板 需要用到扩容—这就用到后面说的链表的好处了,数组是静态的,链表才是真正意义上的动态数据结构)

2.数组的定义和初始化

1.数组的定义:
数据类型[] 数组名;//int[] a;
数据类型 数组名[]; //int a[];

2.数组的创建:三种方式
int[] a=new int[10];
int[] a={a,b,c,d};
int[] a=new int[]{a,b,c,d};

3.数组的索引(index):
[0,数组名.length)
第一个位置索引是0
最后一个位置索引是length-1

3.数组的遍历

1.for循环

int[] a={1,2,3,4};
        for (int i=0;i<a.length;i++){
            System.out.print(a[i]+"------");
        }

在这里插入图片描述

2.增强for循环

 int[] a={1,2,3,4};
        for (int arr:a){//arr是给要遍历的a数组临时取的名字
            System.out.print(arr+"-----");
        }

在这里插入图片描述

小总结:for循环知道索引,可以拿到想要的值,增强for循环没有索引,全部遍历出来

3.最简单的直接用人家提供的Arrays.toString(数组名)

 int[] a={1,2,3,4};
        System.out.print(Arrays.toString(a));

在这里插入图片描述

4.数组的基本操作(不多说 注解很详细)

    package com.ffyc.datastructure;

    import java.util.Arrays;
    import java.util.Objects;
    import java.util.Random;

    //数组
    public class MyArray<T> {//写成泛型  就可以存多种数据类型
        /*创建自己的数组  基于java中的数组 进行二次封装  制作属于我们自己的可变数组  操作增删改查*/

        /*泛型  然后增加是扩容(创建新数组)、删除缩容 */

        //1.创建数组 初始化
       private T[] data;//数组的数据容器 用来保存自己数组的
        private int size;//实际保存数据的个数   永远指向待插入位置的索引
        /*get/set方法  可获得数组和数组长度*/

        //构造方法 有参无参

        MyArray() {//无参
            this(20);//默认创建容量为20的数组
        }

        MyArray(int capacity) {//有参  创建一个数组 当然要指定容量了
        this.size=0;
        data= (T[]) new Object[capacity];//T是不可以直接new的 可以先newObjects 再强制类型转换创建成T

        }



        //2.数组的方法

        //2.1判断数组是否为空
        public boolean isEmpty(){
               return this.size==0;
        }

        //2.2获取数组中实际保存元素的个数
      /*  public int getSize(){
            return this.size;
        }*/
    //这个方法已经有了  直接用就可以

        //2.3 增 向数组末尾添加元素
        public void addTail(T ele){
            //直接调add 索引为size
            add(this.size,ele);
        }


        //2.3 增 向数组头部添加元素
        public void addHead(T ele){
            //直接调add  索引为0即可
            add(0,ele);
        }

        //2.3 增  向指定位置(任意位置)添加元素 牵扯元素后移 循环 从后面开始移
        /*添加操作:插前判断 插后加加    */
        public void add(int index,T ele){
            if (index<0||index>size){//判断数组索引位置是否有效
                throw new IllegalArgumentException("index is error");
            }
            //位置有范围  还有满了不能插入  都需要判断
            if (this.size==data.length){//判断数组是否已满
               /* throw new IllegalArgumentException("this array is full");*/
            //如果数组满  就扩容
       resize(2*data.length);//更改数组容器
            }

            //在index位置插 要将index及以后的都后移  从最后面开始移
            for (int i=size-1;i>=index;i--){
                data[i+1]=data[i];//后移操作  把把前一个位置上的数赋值给后面 空出一个位置(即就是待插入元素的位置)
            }
            data[index]=ele;
            this.size++;//记得长度++
        }



        //改变数组容器 可扩容也可缩容
        public void resize(int newCapacity){
            T[] newData= (T[]) new Object[newCapacity];//new一个新数组  然后复制进去(循环)
            for (int i=0;i<this.size;i++){
                newData[i]=data[i];
            }
            this.data=newData;//把新数组替换调原来的数组
        }

        //2.6  查   获取指定位置的元素
        public T getEleByIndex(int index){
            //判断数组越界
            if (index<0||index>=size){
                throw new IllegalArgumentException("index is error");
            }
            return data[index];
        }




        //2.5  改  修改指定位置的元素
        public void updataByIndex(int index,T ele){
            //判断数组越界
            if (index<0||index>=size){
                throw new IllegalArgumentException("index is error");
            }
            data[index]=ele;
        }


        //2.7  包含(搜索)操作  判断数组中是否包含指定元素  循环就可以
        public int isContains(T ele){
            for (int i=0;i<this.size;i++){
                if (this.data[i].equals(ele)){
                    return i;//找到返回索引
                }
            }
            return -1;//遍历完还没找到  就是不包含 返回-1
        }

        /*这里的删除只能删除第一次出现的*/
        //2.4 删  删除指定位置的元素  元素前移  长度-1
        public T remove(int index){
            //判断位置是否有效
            if (index<0||index>=size){
                throw new IllegalArgumentException("index is invalid");//无效索引
            }
            //位置有效就开始操作   前移
            T result=data[index];//一定要放在删除之前先保存
            for (int i=index+1;i<size;i++){//从待删元素的后一个元素开始前移
                data[index]=data[index+1];//前移
            }
            this.size--;
            data[size]=null;//前移占了删除位置  后面就空一个位置
            //返回删除元素的位置
            //删除之后进行缩容操作
            if (this.size==data.length/4&&data.length/2>0){//加条件data.length/2>0 因为缩容1/2是0  不能缩容到0  1/4 真正不需要那么多的时候才缩容  解决复杂度震荡(删一个增一个 又扩又缩)
                resize(data.length/2);
            }

            return result;
        }



        //2.4 头删
        public T removeHead() {
            if (isEmpty()){
                return null;
            }
         T result=this.data[0];//记录第一个元素队首元素
           //删除后 把后面的元素前移
            for (int i=1;i<this.size;i++){
             this.data[i-1]=this.data[i];
            }
            this.size-=1;
            //缩容
            if (this.size==data.length/4&&data.length/2>0){//加条件data.length/2>0 因为缩容1/2是0  不能缩容到0  1/4 真正不需要那么多的时候才缩容  解决复杂度震荡(删一个增一个 又扩又缩)
                resize(data.length/2);
            }
            return result;
        }

        //2.4  尾删
        public T removeTail(){
            if (isEmpty()){
                return null;//判断数组是否为空 为空就没得删了
            }
            T result=this.data[--this.size];//记录尾部的元素  size永远指向待插入元素的位置先-- 先--才是最后一个元素
            //缩容
            if (this.size==data.length/4&&data.length/2>0){//加条件data.length/2>0 因为缩容1/2是0  不能缩容到0  1/4 真正不需要那么多的时候才缩容  解决复杂度震荡(删一个增一个 又扩又缩)
                resize(data.length/2);
            }
            return result;
        }

        //2.4  删  删除指定元素 返回删除元素的位置
        public int removeEle(T ele){
            //判断待删除元素是否存在
             int index= isContains(ele);//判断元素是否存在 返回一个索引 存在就用这个索引直接删
            if (index==-1){
                return -1;
            }else {
                remove(index);
            }
            return index;//返回删除元素的位置
        }


        //2.8   遍历操作  把数组中每个元素进行输出  写到toString方法中
        @Override
        public String toString() {
         StringBuilder sb=new StringBuilder();
         sb.append("[");//开始的时候放左括号
            //遍历
            for (int i=0;i<this.size;i++){
                sb.append(data[i].toString());
                //逗号隔开
                if(i!=this.size-1){
                    sb.append(",");
                }
            }
            sb.append("]");//结束的时候追加右括号  就都在括号里了
            return sb.toString();
        }



        //下面get、set方法
        public T[] getData() {
            return data;
        }

        public void setData(T[] data) {
            this.data = data;
        }

        public int getSize() {
            return size;
        }

        public void setSize(int size) {
            this.size = size;
        }

        public static void main(String[] args) {
            MyArray<Integer> myArray=new MyArray<Integer>(10);
            int count=20;//嘿嘿  多少个都可以添加进去
            //添加操作  随机数添加
            Random random=new Random();
            for (int i=0;i<count;i++){
               myArray.addTail(random.nextInt(10));//加Integer.MAX_VALUE就都是整数
            }
            System.out.println("数组:"+myArray);

           //判断10是否在数组中
            System.out.println("2是否存在:"+(myArray.isContains(2)==-1?false:true));

    MyArray<String> strArray=new MyArray<>();
            strArray.addTail("qw");
            strArray.addTail("er");
            strArray.addTail("r");
            strArray.addTail("q");
            strArray.addTail("k");
            System.out.println("字符串:"+strArray);//默认调toString方法
            System.out.println("c是否存在:"+(strArray.isContains("c")==-1?false:true));
            strArray.add(2,"123");
            System.out.println("字符串:"+strArray);//默认调toString方法
        }
    }

测试结果:

在这里插入图片描述

5.操作的时间复杂度

O(1)<O(n)<O(lgn)<Onlogn<O(n^2)

增加和删除:遍历一遍数组 时间复杂度O(n)
查找和修改:已知索引O(1),位置索引O(n) 因为未知索引需要遍历一遍
增加的时候resize扩容:均摊复杂度 O(1)

均摊思想:
不同情况下时间复杂度出现级别差别,就比如未满是插入是O(1),满了插入要扩容O(n),基本是低级,偶尔高级,将高的均摊到低的 下来整体就是O(1)
n次O(1)的操作=1次O(n)的操作 平均就是1次O(1)

复杂度的震荡:
数组满了的时候新增就会扩容,扩容后又删除,用不到那么多空间就会缩容,频繁这样操作就会又扩又缩,太急着缩容了太勤快

解决办法:Lazy
让size==capacity/4时,才会缩容 即减半

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82879.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RRT_star MATLAB

colormap 函数 创建栅格地图 clc clear close all%% 构建颜色MAP图 cmap [1 1 1; ... % 1-白色-空地0 0 0; ... % 2-黑色-静态障碍1 0 0; ... % 3-红色-动态障碍1 1 0;... % 4-黄色-起始点 1 0 1;... % 5-品红-目标点0 1 0…

Canal同步mysql binlog至pulsar

Canal 一、简介 canal [kə’nl]&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费 基于日志增量订阅和消费的业务包括 数据库镜像数据库实时备份索引构建和实时维护(拆分异构索引、倒排索引等)业务 cache 刷新带业务逻辑的增量数据处…

【数据结构】队列(链式队列)

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 队列的结构和概念&#xff1a; Queue.h文件 Queue.c文件 Test.c文件&am…

ElasticSearch分布式架构原理

一个ES集群中有多个Server节点&#xff0c;每个Server节点中含有多个Index。 主节点&#xff08;Master&#xff09; 主资格节点的主要职责是和集群操作相关的内容&#xff0c;如创建或删除索引&#xff0c;跟踪哪些节点是集群的一部分&#xff0c;并决定哪些分片分配给相关的…

文件系统篇

目录 1.文件系统的基本组成 1.1.文件 1.1.1.目录项和目录是一个东西吗&#xff1f; 1.1.2.那文件数据是如何存储在磁盘的呢&#xff1f; 2.page cache 2.1.进程写文件时&#xff0c;进程发生了崩溃&#xff0c;已写入的数据会丢失吗 2.2.page cache是什么&#xff1f; …

Docker:网络配置

目录 一、网络模式简介 二、bridge模式以及host模式的命令演示 bridge模式 host模式 三、自定义网络 一、网络模式简介 Docker在创建容器时有四种网络模式&#xff1a;bridge/host/container/none&#xff0c;bridge为默认不需要用--net去指定&#xff0c;其他三种模式需要…

CAS机制和synchronize的原理及其优化机制(锁消除 偏向锁 自旋锁 膨胀锁 锁粗化)

乐观锁的问题&#xff1a;并不总是能处理所有问题&#xff0c;所以会引入一定的系统复杂度。 读写锁 把加锁操作分成了俩种 一是读锁二是写锁 也就是说在读和读之间是没有互斥的 但是在读写和写写之间就会存在互斥 如果一个场景是一写多度 那么使用这个效率就会很高 重量级锁…

【数据结构与算法】B_树

目录 前言&#xff1a; 一、B树 1、B树概念 2、B树查找 3、B树插入 4、B树前序遍历 5、B树性能 二、B、B*树 1、B树概念 2、B树的插入 2、B*树概念 3、总结 三、B系列树的应用 总结 前言&#xff1a; 我们已经有很多索引的数据结构了 例如&#xff1a; 顺序查找 …

CAD外部参照文件的分解

最近遇到一个编图要求&#xff1a; “图纸文件的内容主要由模型空间和布局空间内的信息组成&#xff0c;尽量减少外部参照的使用。” 我们的综合图分幅主要依照外部参照来的&#xff0c;图件的本体只有1个&#xff0c;分幅图中只有布局试图有点线面等实体存在&#xff0c;模型…

阿里二面:用过GC日志可视化工具进行JVM调优吗?

上周有个小伙伴面了阿里&#xff0c;在二面中被问到GC日志分析&#xff0c;感觉回答的不是很好&#xff0c;过来找我复盘&#xff0c;大致听了他的回答&#xff0c;虽然回答出了部分&#xff0c;但是没抓到重点。 GC日志分析算是JVM调优中比较难的部分&#xff0c;今天这篇文章…

0123 双指针 Day12

剑指 Offer 25. 合并两个排序的链表 输入两个递增排序的链表&#xff0c;合并这两个链表并使新链表中的节点仍然是递增排序的。 示例1&#xff1a; 输入&#xff1a;1->2->4, 1->3->4 输出&#xff1a;1->1->2->3->4->4 /*** Definition for si…

安科瑞嵌入式多功能计量表AEM96 精度0.5S级 2-31次分次谐波

安科瑞 王晶淼/刘芳 一、产品概述 AEM系列三相嵌入式电能计量表是一款主要针对电力系统、工矿企业、公用设施的电能统计、管理需求而设计的智能电能表&#xff0c;集成三相电力参数测量及电能计量与考核管理&#xff0c;提供上24时&#xff0c;上31日以及上12月的电能数据统计…

DNS 区域传送漏洞(dns-zone-tranfer)学习

DNS 区域传送漏洞&#xff08;dns-zone-tranfer&#xff09;学习 ———— 相关知识理解 DNS&#xff08;域名系统&#xff09;就像一个互联网电话簿。它负责将人类可读的主机名解析为机器可读的 IP 地址。 DNS服务器分为主服务器&#xff0c;备份服务器&#xff0c;缓存服务…

【Docker】多个容器和宿主机之间如何进行数据同步和数据共享?容器数据卷从介绍到常用操作图文教程

专栏往期文章 《Docker是什么&#xff1f;Docker从介绍到Linux安装图文详细教程》《30条Docker常用命令图文举例总结》《Docker如何构建自己的镜像&#xff1f;从镜像构建到推送远程镜像仓库图文教程》 前言 你是否担心 Docker 容器被删除后&#xff0c;容器内的重要数据就丢…

VFIDILDKVENAIHNAAQVGIGFAKPFEKLINPK,果蝇抗菌肽

果蝇抗菌肽是一种含有Lys的抗菌多肽&#xff0c;序列中包含34个氨基酸&#xff0c;是一种含有α-折叠的抗菌多肽。 编号: 223981中文名称: 果蝇抗菌肽&#xff0c;Andropin英文名: Antimicrobial Peptide Andropin单字母: H2N-VFIDILDKVENAIHNAAQVGIGFAKPFEKLINPK-OH三字母: H2…

自然语言处理(NLP)数据集汇总 3(附下载链接)

&#x1f384;&#x1f384;【自然语言处理NLP】简介 &#x1f384;&#x1f384; 自然语言处理(Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自然语言处理是一门…

Allure:根据step动态设置description

背景 使用pytestAllure进行自动化的时候,为了报告展示更明确会使用 with allure.step(xxx)和 allure.step(xxx)测试结束后就可以看到 测试步骤 Allure还支持配置Description 之前直接在case中编写,例如 """ [用例描述]: 专家问诊 [前置步骤]:1. 打开h5页面…

ScheduledExecutorService的使用及守护线程

只运行一次 private static ScheduledExecutorService scheduler; public static void main(String[] args) throws Exception { scheduler Executors.newScheduledThreadPool(5); // 循环任务&#xff0c;按照上一次任务的发起时间计算下一次任务的开始时间 scheduler.schedu…

解决mysql存储emoji表情唯一索引报错问题

问题发现&#xff1a; 1、正常上班的一天&#xff0c;突然间有运营同事反馈&#xff0c;我们在添加数据的时候&#xff0c;发现添加了&#x1f438;之后&#xff0c;对应的&#x1f4a9;没有了&#xff0c;添加了&#x1f4a9;然后&#x1f438;就没有了&#xff0c;需要研发帮…

【Linux】四、Linux 进程概念(四)|进程地址空间

目录 十、进程地址空间 10.1 回顾C/C 地址空间 10.2 测试 10.3 感性理解虚拟地址空间 10.4 如何画大饼&#xff1f; 10.5 如何理解区域划分和区域调整 10.6 虚拟地址空间、页表和物理地址 10.7 为什么存在地址空间 10.7.1 保证物理内存的安全性 10.7.2 保证进程的独立…