数据结构(数组实现)

数组是应用最广泛的一种数据结构,常常被植入到编程语言中,作为基本数据类型使用,因此,在一些教材中,数组并没有被当做一种数据结构单独拿出来讲解(其实数组就是一段连续的内存,即使在物理内存中不是连续的,在逻辑上肯定是连续的)。其实没必要在概念上做纠缠,数组可以当做学习数据结构的敲门砖,以此为基础,了解数据结构的基本概念以及构建方法

数据结构不仅是数据的容器,还要提供对数据的操作方法,比如检索、插入、删除、排序等。

无序数组(假设数组中,没有重复的值)

package www.panda.array;

/**
 * @Author: panda
 * @Data: 2018/12/2 21:19
 * @Version: 1.0
 * @remark 没有实现数组扩容,想要实现,各位同学自己拓展
 */
public class DisorderlyArray<E> {

    private String[] stringsArray;

    private static int size = 0;

    private static final int ERROEINDEX = -1;

    public DisorderlyArray(int capacity){
        if(capacity <= 0) throw new IllegalArgumentException("数组的长度不能小于或等于0");
        stringsArray = new String[capacity];
    }

    //新增
    public void insertElem(String value){
        stringsArray[size++] = value;
    }

    //查看是否包含元素
    public int containsElem(String value){
        for(int i=0;i<stringsArray.length;i++){
            if(stringsArray[i].equals(value)){
                return i;
            }
        }
       return ERROEINDEX;
    }

    //通过下标得到元素
    public String getElem(int index){
        if(index <= 0) throw new IllegalArgumentException("没有此下表元素");
        return stringsArray[index];
    }

    //通过值删除元素
    public Boolean deleteElem(String value){
        int index = -1;
        if((index = containsElem(value)) != -1){
            for(int i=index;i<size;i++){
                stringsArray[i]=stringsArray[i+1];
            }
            size--;
            return true;
        }else{
            return false;
        }
    }

    //通过下标修改值
    public void updateElemByIndex(int index,String value){
        stringsArray[index] = value;
    }

    //遍历所有元素
    public void display(){
        for(int i=0;i<size;i++){
            System.out.print(stringsArray[i]+"\n");
        }
    }

    //返回数组的长度
    public int getSize(){
        return size;
    }

    public static void main(String[] args){
        DisorderlyArray disorderlyArray = new DisorderlyArray(10);
        disorderlyArray.insertElem("张三");
        disorderlyArray.insertElem("李四");
        disorderlyArray.insertElem("王五");
        disorderlyArray.insertElem("赵六");
        String elem = disorderlyArray.getElem(1);
        System.out.print(elem);
        disorderlyArray.updateElemByIndex(1,"猴八");
        disorderlyArray.deleteElem("赵六");
        disorderlyArray.display();
        System.out.print(disorderlyArray.getSize());
    }

}

无序数组的特点:插入快,假设知道下标,可以很快获取到元素

无序数组的缺点:删除慢,查找慢

有序数组(假设数组中是没有重复值的,数据是从小到大的顺序排列的)

package www.panda.array;

/**
 * @Author: panda
 * @Data: 2018/12/2 22:10
 * @Version: 1.0
 * @remark 当前是1.1 新增二分查找,以及二分查找优化 
 */
public class OrderlyArray<E> {

   private int[] intArray;

    private int size = 0;

    private static final int ERRORVALUE = -1;

    public OrderlyArray(int capacity){
        if(capacity <= 0) throw new IllegalArgumentException("数组的长度不能小于或等于0");
        this.intArray = new int[capacity];
    }


    //增加元素
    public void insertElem(int elem){
        int index = 0;
        for(;index<size;index++){
            if(intArray[index] > elem){//如果当前元素大于,目标元素,结束循环
                break;
            }
        }
        for(int i=size;i>index;i--){
            intArray[i] = intArray[i - 1];//前一位赋值给后一位
        }
        intArray[index] = elem;
        size++;
    }

    //通过要查找的值,得到数组的下标
    public int getIndex(int value){
        for(int i=0;i<size;i++){
            if(intArray[i] == value){
                return i;
            }
        }
        return ERRORVALUE;
    }

    /**
     * 简单版的二分查找
     * @param array
     * @param value
     * @return
     */
    public int easyBinarySearch(int[] array,int value){
        int lower = 0,upper = array.length-1,center = 0;
        if(center < intArray[lower] || center> intArray[upper] || lower > upper){
            return ERRORVALUE;
        }
        while(lower <= upper){
            center = (lower+upper)/2;
            if(array[center] == value){
                return center;
            }else if(value > array[center]){
                lower = center + 1;
            }else if(value < array[center]){
                upper = center - 1;
            }
        }
        return ERRORVALUE;
    }


    /**
     *  对二分查找进行了优化,性能提高了30% 到 80%
     * @param array
     * @param value
     * @return
     */
    public static int optimizeBinarySearch(int[] array,int value){
        int lower = 0,upper = array.length-1,center = 0;
        while(lower + 1 != upper){
            center = (upper + lower)/2;
            if(array[center] < value)
                lower = center;
            else
                upper =center;
        }
        if(upper >= array.length || array[upper] != value)
            upper = ERRORVALUE;
        return upper;
    }

    //通过下标获取到元素
    public int getElem(int index){
        if(index <= 0) throw new IllegalArgumentException("没有此下表元素");
        if(index>size-1) throw new ArrayIndexOutOfBoundsException("数组下标越界了");
        return intArray[index];
    }

    //删除数组中的元素
    public void deleteElem(int elem){
        int index = -1;
        for(int i=0;i<size;i++){
            if(intArray[i] == elem){
                index = i;
                break;
            }
        }
        if(index >= 0){
            for(int i=index;i<size-1;i++){
                intArray[i] = intArray[i + 1];
            }
            size--;
        }else{
            //这里不自定义异常了,各位同学可以自己拓展
            System.out.println("没有找到你想要删除的值");
        }
    }

    //查询所有的元素
    public void display(){
        for(int i=0;i<size;i++){
            System.out.print(intArray[i]+"\n");
        }
    }

    //得到整个数组的长度
    public int getSize(){
        return size;
    }

    public static void main(String[] args){
        int[] intArray ={1,2,3,4,5,6};
        int i = OrderlyArray.optimizeBinarySearch(intArray,4);
        System.out.println(i);
        OrderlyArray<Object> objectOrderlyArray = new OrderlyArray<>(10);
        int i1 = objectOrderlyArray.easyBinarySearch(intArray, 2);
        System.out.println(i1);
         objectOrderlyArray.insertElem(1);
        objectOrderlyArray.insertElem(2);
        objectOrderlyArray.insertElem(3);
        objectOrderlyArray.insertElem(4);
        objectOrderlyArray.deleteElem(5);
        int size1 = objectOrderlyArray.getSize();
        objectOrderlyArray.display();
    }



}

lower和upper指向数组的第一个和最后一个非空数据项。通过设置这些变量可以确定查找的范围。然后再while循环中,当前的下标center被设置为这个范围的中间值

如果center就是我们要找的数据项,则返回下标,如果不是,就要分两种情况来考虑:如果center指向的数据项比我们要找的数据小,则证明该元素只可能在center和upper之间,即数组后一半中(数组是从小到大排列的),下轮要从后半段检索;如果center指向的数据项比我们要找的数据大,则证明该元素只可能在lower和center之间,下一轮要在前半段中检索

有序数组的特点:采用二分查找,查找速度很快(以及优化版二分查找)

有序数组的缺点:删除慢,插入慢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值