数据结构(1):使用面向对象模拟数组

数组是一种常用的数据结构,数组具有不可变性,创建后的数组的长度固定,通过索引访问数组中的元素,访问速度快,删除添加效率低。

通过面向对象模拟数组,模拟的数组具有以下功能:

  1. 添加新元素
  2. 展示
  3. 查找元素所在位置
  4. 根据索引获取元素
  5. 根据索引删除元素
  6. 修改指定位置的元素

同时使用两个算法对数组进行操作:

  1. 有序添加元素
  2. 二分查找法

1.创建数组类 MyArray.java

数据如何存储呢?在类中添加一个数组类型的私有属性用来保存数据,同时添加一个变量存储有效数据的长度(也就是元素的个数)

创建数组的时候需要指定数组的长度,所以要添加两个构造方法:

1.无参构造方法设置数组默认长度
2.有参构造方法指定数组长度

public class MyArray {
    //存储元素
    private long[] arr;
    //表示有效数据的长度
    private int elements;

    //无参构造默认50个长度
    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }
}

2.编写添加数据的方法

elements 属性的默认值是 0,第一次向对象中添加元素也是添加到索引为0 的元素中,添加后将 elements 的长度加1,就能一直向数组中添加元素了,添加元素的个数取决于 arr 的长度。

public void insert(long value) {
    arr[elements]=value;
    elements++;
}

3.编写展示数据的方法

简单的展示数组中的元素即可,使用 for 循环遍历

public void display() {
    System.out.print("[");
    for (int i = 0; i < elements; i++) {
        System.out.print(arr[i]+" ");
    }
    System.out.println("]");
}

4.编写查找数据的方法

思路:使用循环遍历数组 arr ,将要查找的数据和 arr 中每个元素进行比较。如果相等,则跳出循环。循环结束后,如果循环次数等于元素个数说明没有找到数据,返回-1。否则返回循环次数(即找到的索引)。

public int search(long value) {
    int i ;
    for (i = 0; i < elements; i++) {
        if(value==arr[i]) {
            break;
        }
    }
    //遍历到末尾说明没有找到
    if (i==elements) {
        return -1;
    }else {
        return i;
    }
}

5.根据索引获取元素

思路:这相对比较简单了,直接给 arr 索引就能获取到元素。但是要注意传入的索引必须可用,不能用的索引可以抛出异常。

public long get(int index) {
    //如果索引大于可用,或索引小于0 都是无效的索引
    if (index>=elements||index<0) {
        //抛出数组越界异常
        throw new ArrayIndexOutOfBoundsException();
    }else {
        return arr[index];
    }
}

6.根据索引删除元素

思路:和获取元素时一样,先检查索引是否可用。如果可用,就从要删除元素的位置开始向后遍历,每次都将下一个元素的值赋值给当前元素。也就相当于要删除的元素被下一个元素覆盖,下一个元素被下下一个元素覆盖,以此类推。元素移动完成后,将可用元素长度 elements 减1。

public void delete(int index) {
    //如果索引大于可用,或索引小于0 都是无效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        for(int i=index;i<elements;i++) {
            arr[index]=arr[i+1];
        }
        elements--;
    }
}

7.修改指定位置的元素

思路:和获取差不多,就是把获取改为修改

public void change(int index,int newValue) {
    //如果索引大于可用,或索引小于0 都是无效的索引
    if (index>=elements||index<0) {
        throw new ArrayIndexOutOfBoundsException();
    }else {
        arr[index]=newValue;
    }
}

8.完整代码

public class MyArray {
    private long[] arr;
    //表示有效数据的长度
    private int elements;

    public MyArray() {
        arr=new long[50];
    }

    public MyArray(int maxsize) {
        arr=new long[maxsize];
    }

    /**
     * 添加数据
     * @param value
     */
    public void insert(long value) {
        arr[elements]=value;
        elements++;
    }

    /**
     * 显示数据
     */
    public void display() {
        System.out.print("[");
        for (int i = 0; i < elements; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println("]");
    }

    /**
     * 查找数据
     */
    public int search(long value) {
        int i ;
        for (i = 0; i < elements; i++) {
            if(value==arr[i]) {
                break;
            }
        }
        //遍历到末尾说明没有找到
        if (i==elements) {
            return -1;
        }else {
            return i;
        }
    }

    /**
     * 查找数据,根据索引来查
     */
    public long get(int index) {
        //如果索引大于可用,或索引小于0 都是无效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            return arr[index];
        }
    }

    /**
     * 删除数据
     */
    public void delete(int index) {
        //如果索引大于可用,或索引小于0 都是无效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            for(int i=index;i<elements;i++) {
                arr[index]=arr[i+1];
            }
            elements--;
        }
    }

    /**
     * 更新数据
     */
    public void change(int index,int newValue) {
        //如果索引大于可用,或索引小于0 都是无效的索引
        if (index>=elements||index<0) {
            throw new ArrayIndexOutOfBoundsException();
        }else {
            arr[index]=newValue;
        }
    }
}

9.有序添加元素

思路:修改 insert 方法,遍历 arr 数组,如果当前元素大于添加的数据,当前的位置就要存入的位置。从最后一个元素开始,逐个将元素向后位移,空出要存入的位置。存入要添加的元素后,将有效数据长度加1。

public void insert(long value) {
    int i;
    for(i=0;i<elements;i++) {
        if(arr[i]>value) {
            break;
        }
    }
    for (int j = elements; j > i; j--) {
        arr[j]=arr[j-1];
    }
    arr[i]=value;

    elements++;
}

10.二分查找法

思路:数据必须是有序的,才能使用二分查找法!可以结合有序添加元素一块使用,这里的序列是升序(从小到大)。二分查找是每次和一组数中间的数进行比较,如果大于就再和右边的数最中间的数比较,如果小于就和左边的数最中间的数比较。直到中间的数和要查找的数相等,否则就是没有这个数。

public int binarySearch(long value) {
    int mid=0;//中间值
    int low=0;
    int high = elements;

    while(true) {
        mid=(high+low)/2;
        if(arr[mid]==value) {
            return mid;
        }else if(low>high) {
            return -1;
        }else {
            if (value>arr[mid]) {
                high=mid+1;
            }else {
                high=mid-1;
            }
        }
    }

}

原文地址:https://www.cnblogs.com/AIThink/p/11317642.html

时间: 2024-07-30 22:30:58

数据结构(1):使用面向对象模拟数组的相关文章

Java程序员的JavaScript学习笔记(6——面向对象模拟)

计划按如下顺序完成这篇笔记: 理念. 属性复制和继承. this/call/apply. 闭包/getter/setter. prototype. 面向对象模拟. jQuery基本机制. jQuery选择器. jQuery工具方法. jQuery-在"类"层面扩展. jQuery-在"对象"层面扩展. jQuery-扩展选择器. jQuery UI. 扩展jQuery UI. 这是笔记的第6篇,对前面5篇做一个总结,聊聊JavaScript在面向大型复杂任务时候,如

sql server 模拟数组【转】

sql server 模拟数组 --SQL对字符串的处理能力比较弱,比如我要循环遍历象1,2,3,4,5这样的字符串,如果用数组的话,遍历很简单,但是T-SQL不支持数组,所以处理下来比较麻烦.下边的函数,实现了象数组一样去处理字符串.一,用临时表作为数组create function f_split(@c varchar(2000),@split varchar(2)) returns @t table(col varchar(20)) as begin while(charindex(@sp

数据结构学习(一)数组

数组回顾: 一.创建数组 1.创建数组 int[] arr=new int[10]; 创建一个长度为10的int类型的数组 long[] array=new long[10]; 创建long类型的数组 2.往数组中增加元素 arr[0]=1; 往数组的0元素的位置增加一个元素1 二.访问数组中的数据 int i=arr[0]; 从数组中获取0元素的数组 三.数组初始化 long[] arr=new long[]{2,3,4}//初始化arr[0]=1//修改值System.out.println

数据结构基础(1)--数组C语言实现--动态内存分配

数据结构基础(1)--数组C语言实现--动态内存分配 基本思想:数组是最常用的数据结构,在内存中连续存储,可以静态初始化(int a[2]={1,2}),可以动态初始化 malloc(). 难点就是数组在删除或者插入元素的时候,要移动元素的坐标不好确定.规律: 1.如果要在数组中第pos个位置插入一个元素(应该从后面开始移动) for( i=cnu;i>=pos;i--) pBase[i]=pBase[i-1]; 2.删除数组第pos位置的元素 for(i=pos+1;i<=cnu;i--)

数据结构之C语言模拟整数数组实现

#include <stdio.h> #include <malloc.h> #include <stdlib.h> typedef struct Arr { int *pBase; //数组第一个元素地址 int len; //数组长度 int cnt; //当前有效元素数量 } Array; void init_array(Array *, int); //初始化数组 void show_array(Array *); //遍历打印数组 bool is_empty(

数据结构实践——排队看病模拟(队列)

本文是针对数据结构基础系列网络课程(3):栈和队列的实践项目. [项目 - 排队看病模拟] 编写一个程序,反映病人到医院看病,排队看医生的情况.在病人排队过程中,主要重复两件事: (1)病人到达诊室,将病历本交给护士,排到等待队列中候诊. (2)护士从等待队列中取出下一位病人的病历,该病人进入诊室就诊. 要求模拟病人等待就诊这一过程.程序采用菜单方式,其选项及功能说明如下: (1)排队--输入排队病人的病历号,加入到病人排队队列中. (2)就诊--病人排队队列中最前面的病人就诊,并将其从队列中删

算法与数据结构基础1:动态数组

恶补算法与数据结构,从很基础的开始,先看动态数组的实现. // array.h #include <iostream> #include <cstring> #include <cstdlib> using namespace std; class Array { public: // ************************************************************************** // 类的四大函数:构造函数.拷贝构

【数据结构与算法01】数组

数组是应用最广泛的数据存储结构.它被植入到大部分的编程语言中,由于数组十分易懂,所以在这里就不赘述,主要附上两端代码,一个是普通的数组,另一个是有序数组.有序数组是按关键字升序(或降序)排列的,这种排列使快速查找数据项成为可能,即可以使用二分查找. 普通数组的Java代码: public class GeneralArray { private int[] a; private int size; //数组的大小 private int nElem; //数组中有多少项 public Gener

Java千百问_06数据结构(014)_java数组如何存储在内存中

点击进入_更多_Java千百问 1.数组的内存空间是何时分配的 java中的数组是用来存储同一种数据类型的数据结构,一旦初始化完成,即所占的空间就已固定下来,初始化的过程就是分配对应内存空间的过程.即使某个元素被清空,但其所在空间仍然保留,因此数组长度将不能被改变. 了解什么是数组看这里:java中的数组是什么 当仅定义一个数组变量(int[] numbers)时,该变量还未指向任何有效的内存,因此不能指定数组的长度,只有对数组进行初始化(为数组元素分配内存空间)后才可以使用. 数组初始化分为静