0
点赞
收藏
分享

微信扫一扫

数据结构——数组

phpworkerman 2022-02-11 阅读 83

数据结构

首先,我们来了解一下什么是数据结构?为什么要学习数据结构?

一、什么是数据结构?

1、是一门基础学科

2、它研究的是数据如何在计算机中进行组织和存储,使得我们可以高效的获取数据和修改数据

3、数据结构可以分为三类:

  • 线性结构:数组、队列、栈、链表、哈希表…
  • 树形结构:二叉树、二分搜索树、AVL树、红黑树、堆、Trie树、线段树、并查集…
  • 图结构:邻接矩阵、邻接表
    4、为什么要学习数据结构?
    根据不同的应用,灵活选择最合适的数据结构
    数据结构+算法=程序
    5、使用环境
    IDEA、JDK8+

二、接下来进入我们数据结构的第一个内容——数组

首先让我们回顾一下Java数组的使用

 public static void main(String[] args) {
        /**
         * 数组的概念
         * 数组:是用来存储一组**相同类型**的数
         * Java中数组的定义:
         * 数组类型[] 数组名
         * 初始化数组:1、数据类型[] 数组名 = new 数据类型[数组长度];
         * 2、数组类型[] 数组名 = {和数组类型同类型的数}
         * 代码的限制:在方法函数中,有长度限制,
         *           圈复杂度:嵌套不能超过6层
         */

        //遍历数组
        String[] str ={"chi","he","wan","shui"};
        /*一般情况下是for循环遍历*/
        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }
        /*用流优化数组遍历*/
        //将数组转成流         遍历数组
        Arrays.stream(str).forEach(System.out::println);//第一种方法
        Arrays.stream(str).forEach(item->System.out.println(item));//第二种方法
    }

public static void main(String[] args) {
		/*数组的使用*/
        String[] fruits = {"apple", "banana", "pear", "watermelon", "Pineapple"};
        /*for循环
        for (int i = 0; i < fruits.length; i++) {
            System.out.println(fruits[i]);
        }*/

        // 使用流遍历,先将数组转成流Arrays.stream(数组名)再用forEach()进行遍历
        Arrays.stream(fruits).forEach(System.out::println);
        //   ->箭头函数
        Arrays.stream(fruits).forEach(item -> System.out.println(item));
        /*创建一个数组就得开辟空间*/
        int[] num = new int[100];
//        1、对每个数据+10
//        2、过滤奇数
        /*生成一个随机数*/
        Random random = new Random();
        for (int i = 0; i < 100; i++) {
            num[i] = random.nextInt(100000);
        }
        /*map()对每个数字进行操作,filter()过滤器,  流:只流一次,可以把所有的操作做完*/
        Arrays.stream(num).map(item->item+10).filter(item->item%2>0).forEach(System.out::println);
    }

在Java数组中经常会出现两个问题:空指针异常问题()和数组越界问题,所以在数据结构中需要对它的边界进行处理。

统计每个字符出现的次数

方法一:

public static void main(String[] ag){
String str = "aaabbbbcccsssddd";
        //统计每个字符出现的次数
        //新建一个map集合
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            //如果集合中不包含该键说明它是第一次出现
            if (!map.containsKey(c)) {
                //向集合中添加键值对put(键,值)
                map.put(c, 1);
            } else {
                //get()方法是返回指定键所对应的值
                map.put(c, map.get(c) + 1);
            }
        }
        //{a=3, b=4, c=3, s=3, d=3}
        System.out.println(map);

方法二:

 public static void main(String[] args) {
        /*出现的次数*/
        String str = "abanhsbckcnncb";//字符串中只包含小写字母
        //英文字母26个
        int[] counts = new int[26];
        /*
        1、先用str.charAt()将获取字符串中的元素(或者用str.toCharArray()将字符串转成数组)
         */
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            //利用编码来统计字母出现的次数
            counts[c - 'a']++;
        }
       //用增强for循环来遍历
        for (int item : counts){
            System.out.println(item);
        }
    }

三、数组的数据结构

使用数组时,最重要的就是数组的索引,通过索引可以对数组进行增删改查操作。
在这里插入图片描述
索引: 可以有语义,也可以没有语义
数组最大的优点:根据索引快速查询。
数组最好应用于索引有语义的情况。并非所有有语义的数字都可以作为数组的索引,例如:
610258122312033366
数组也是可以处理“索引没有语义”的情况。
产生的问题是:
在这里插入图片描述

基于Java中的数组,进行二次封装,制作属于我们自己的数组MySelfArray(可变数组)

在这里插入图片描述
创建一个数组

 	//数组容器,这里我们用到了泛型
    T[] data;
    //实际保存数据的个数
    int size;

    public MySelfArray() {
        this(20);//数组的初始长度
    }

    public MySelfArray(int capacity) {
        //初始化
        this.size = 0;
        //开辟指定长度的数组
        data = (T[]) new Object[capacity];
    }

判断数组是否为空

/**
     * 判断数组是否为空
     *
     * @return boolean
     */
    public boolean isEmpty() {
       /* if(data.length==0){
            return true;
        }
        return false;*/
        return this.size == 0;

    }

向数组里添加元素

/**
     * 向数组的尾部添加元素
     *
     * @param ele 要添加的元素
     */
    public void addDataTail(T ele) {
       /* this.data[size] = ele;
        this.size++;*/
        add(size, ele);
    }
     /**
     * 向数组头部添加元素
     */
    public void addDataHead(T ele) {
       /* for (int i = 0; i < size-1; i++) {
            data[i] = data[i+1];
        }
        data[0]=ele;
        this.size++;*/
        add(0, ele);
    }
 /**
     * 向指定位置添加元素
     *
     * @param index 索引
     * @param ele   要传入的元素内容
     */
    public void add(int index, T ele) {


        if (index < 0 || index > size) {
            throw new IllegalArgumentException("index is error");
        }
        //如果数组已满,进行扩容操作
        resize(2 * data.length);

        for (int i = size-1; i >=index; i--) {
            data[i+1] = data[i];
        }
        data[index] = ele;
        //更新数组
        this.size++;
    }

获取指定位置的元素

 /**
     * 获取指定位置的元素
     *
     * @param index 索引
     * @return 指定位置的元素
     */
    public T getEle(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index is out of XX");
        }
        return data[index];
    }

修改指定位置的元素

   /**
     * 修改指定位置的元素
     *
     * @param index 索引
     * @param ele   内容元素
     */
    public void setIndexEle(int index, T ele) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index is out of XX");
        }
        data[index] = ele;
    }

判断是否包含某个元素

    /**
     * 判断是否包含某个元素
     *
     * @param ele 内容元素
     * @return 是否存在该元素, 并返回该元素的位置
     */
    public int isContians(T ele) {
        for (int i = 0; i < size; i++) {
            if (data[i] == ele) {
                return i;
            }
        }
        return -1;
    }

删除数组中的元素

 /**
     * 删除指定位置的元素
     *
     * @param index 索引
     * @return int
     */
    public T removeIndexEle(int index) {
        if (index < 0 || index >= size) {
            throw new IllegalArgumentException("index is invalid!");
        }
        T reasult = data[index];
        for (int i = index; i < size; i++) {
            data[i] = data[i + 1];
        }
        this.size--;
        data[size] = null;

        //进行缩容操作
        if (this.size == data.length / 2 || data.length / 2 > 0) {
            resize(data.length / 2);
        }

        return reasult;
    }
     /**
     * 删除指定的元素
     * @param ele 内容
     * @return 索引
     */
    public int removeEle(T ele){
        int index = isContians(ele);
        if(index!=-1){
            removeIndexEle(index);
        }
        return index;
    }
/**
     * 删除头元素
     *
     * @param index 索引
     */

    public void removeHead(int index) {
        /*for (int i = index; i < size; i++) {
            data[i+1]=data[i];
        }
        this.size--;
        data[size]=0;*/
        removeIndexEle(0);
    }

数组扩容

 /**
     * 数组扩容,更改数组容积
     *
     * @param newCapacity 新的数组长度
     */
    public void resize(int newCapacity) {
        if (this.size == data.length) {
            T[] newData = (T[]) new Object[newCapacity];
            for (int i = 0; i < this.size; i++) {
                newData[i] = data[i];
            }
            this.data = newData;
        }
    }

基本操作

@Override
    public String toString() {
        return "data=" + Arrays.toString(data);
    }

    public T[] getData() {
        return data;
    }

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

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

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

注意: 使用泛型(“任意”类型的数组)

  • 不可以是基本数据类型(8种 byte char boolean int short float double long),只能是类对象
  • 每种基本数据类型都有一个对应的包装类
举报

相关推荐

0 条评论