zoukankan      html  css  js  c++  java
  • 1.数据结构--数组

     数组是一种最简单的数据结构,它占据一块连续的内存并且顺序存储数据,所以我们需要首先指定数组的大小;

    public class Main {
        public static void main(String[] args) {
            int[] arr = new int[10];
        for(int i = 0; i < arr.length; i++)
            arr[i] = i;
    
        int[] scores = new int[]{100,99,66};
            for(int i = 0; i < scores.length; i++)
                System.out.println(scores[i]); //100 99 66
    
            for(int score: scores)
                System.out.println(score);     //100 99 66
    
            scores[0] = 98;
            for(int score: scores)
                System.out.println(score);     //98 99 66
        }
    }

     1.自定义数组操作方法

    public class Array {
        private int data;
        private int size;
    
        //构造函数,传入数组的容量capacity构造Array
        public Array(int capacity){
            data = new int[capacity];
            size = 0;
        }
    
        //无参数的构造函数
        public Array(){
            this(10);
        }
    
        //获取数组中元素的个数
        public int getSize(){
            return size;
        }
    
        //获取数组的容量
        public int ggetCapacity(){
            return data.length;
        }
    
        //返回数组是否为空
        public boolean isEmpty(){
            return size == 0;
        }
    
        //向所有元素后添加一个新元素
        public void addLast(int e){
            //if(size == data.length)
            //    throw new IllegalArgumentException("AddLast failed,Array is full");
            //data[size] = e;
            //size ++;
            add(size, e);
        }
    
        //向所有元素头添加一个新元素
        public void addFirst(int e){
            add(0, e);
        }
    
        //在第index个位置插入一个新元素e
        public void add(int index,int e){
            if(size == data.length)
                throw new IllegalArgumentException("AddLast failed,Array is full");
    
            if(index < 0 || index > size)
                throw new IllegalArgumentException("AddLast failed,Require index >=0 and index <=size");
    
            for(int i = size -1;i >= index;i --)
                data[i + 1] = data[i];
            data[index] = e;
            size ++;
        }
    
        @Override
        public String toString(){
            StringBuilder res = new StringBuilder();
            res.append(String.format("Array:size= %d, capacity = %d
    ",size,data.length));
            res.append('[');
            for(int i = 0; i < size ;i ++){
                res.append(data[i]);
                if(i != size - 1)
                    res.append(",");
            }
            res.append("]");
            return res.toString();
        }
    
        //获取index索引位置的元素
        public int get(int index){
            if(index < 0 || index >= size)
                throw new IllegalArgumentException("Get Failed,Index is illegal");
            return data[index];
        }
        //获取最后一个位置的元素
    public int getLast(){
    return get(size - 1);
    }

    //获取第一个位置的元素
    public int getFirst(){
    return get(0);
    }

    //修改index所以位置的元素为e public void set(int index,int e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set Failed,Index is illegal"); data[index] = e; } //查找数组中是否有元素e public boolean contains(int e){ for(int i = 0;i < size;i ++){ if(data[i] == e) return true; } return false; } //查找数组中元素e所在的索引,如果不存在元素e,则返回-1 public int find(int e){ for(int i = 0;i < size;i ++){ if(data[i] == e) return i; } return -1; } //从数字组中删除index位置的元素,返回删除的元素 public int remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed,Index is illegal"); int ret = data[index]; for(int i = index + 1 ;i < size;i ++) data[i - 1] = data[i]; size --; return ret; } //从数组中删除第一个元素,返回删除的元素 public int removeFirst(){ return remove(0); } //从数组中删除最后一个元素,返回删除的元素 public int removeLast(){ return remove(size - 1); } //从数组中删除元素e public void removeElement(int e){ int index = find(e); if(index != -1) remove(index); } }

     调用自定义的数组方法

    //把数组码成一排进行存放
    public class Main {
        public static void main(String[] args) {
            Array arr = new Array(20);
            for(int i = 0;i < 10; i ++)
                arr.addLast(i);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[0,1,2,3,4,5,6,7,8,9]
    
            arr.add(1,100);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[0,100,1,2,3,4,5,6,7,8,9]
    
            arr.addFirst(-1);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[-1,0,100,1,2,3,4,5,6,7,8,9]
    
            arr.remove(2);
            System.out.println(arr);
            //[-1,0,1,2,3,4,5,6,7,8,9]
    
            arr.removeElement(4);
            System.out.println(arr);
            //[-1,0,1,2,3,5,6,7,8,9]
    
            arr.removeFirst();
            System.out.println(arr);
            //[0,1,2,3,5,6,7,8,9]
        }
    }

    2.数组使用泛型

    public class Array<E> {
        private E[] data;
        private int size;
    
        //构造函数,传入数组的容量capacity构造Array
        public Array(int capacity){
            data = (E[])new Object[capacity];
            size = 0;
        }
    
        //无参数的构造函数
        public Array(){
            this(10);
        }
    
        //获取数组中元素的个数
        public int getSize(){
            return size;
        }
    
        //获取数组的容量
        public int ggetCapacity(){
            return data.length;
        }
    
        //返回数组是否为空
        public boolean isEmpty(){
            return size == 0;
        }
    
        //向所有元素后添加一个新元素
        public void addLast(E e){
            //if(size == data.length)
            //    throw new IllegalArgumentException("AddLast failed,Array is full");
            //data[size] = e;
            //size ++;
            add(size, e);
        }
    
        //向所有元素头添加一个新元素
        public void addFirst(E e){
            add(0, e);
        }
    
        //在第index个位置插入一个新元素e
        public void add(int index,E e){
            if(size == data.length)
                throw new IllegalArgumentException("AddLast failed,Array is full");
    
            if(index < 0 || index > size)
                throw new IllegalArgumentException("AddLast failed,Require index >=0 and index <=size");
    
            for(int i = size -1;i >= index;i --)
                data[i + 1] = data[i];
            data[index] = e;
            size ++;
        }
    
        @Override
        public String toString(){
            StringBuilder res = new StringBuilder();
            res.append(String.format("Array:size= %d, capacity = %d
    ",size,data.length));
            res.append('[');
            for(int i = 0; i < size ;i ++){
                res.append(data[i]);
                if(i != size - 1)
                    res.append(",");
            }
            res.append("]");
            return res.toString();
        }
    
        //获取index索引位置的元素
        public E get(int index){
            if(index < 0 || index >= size)
                throw new IllegalArgumentException("Get Failed,Index is illegal");
            return data[index];
        }
    //获取最后一个位置的元素
    public E getLast(){
    return get(size - 1);
    }

    //获取第一个位置的元素
    public E getFirst(){
    return get(0);
    }
    //修改index所以位置的元素为e public void set(int index,E e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set Failed,Index is illegal"); data[index] = e; } //查找数组中是否有元素e public boolean contains(E e){ for(int i = 0;i < size;i ++){ if(data[i].equals(e)) return true; } return false; } //查找数组中元素e所在的索引,如果不存在元素e,则返回-1 public int find(E e){ for(int i = 0;i < size;i ++){ if(data[i].equals(e)) return i; } return -1; } //从数字组中删除index位置的元素,返回删除的元素 public E remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed,Index is illegal"); E ret = data[index]; for(int i = index + 1 ;i < size;i ++) data[i - 1] = data[i]; size --; data[size] = null; //loitering objects != memory leak return ret; } //从数组中删除第一个元素,返回删除的元素 public E removeFirst(){ return remove(0); } //从数组中删除最后一个元素,返回删除的元素 public E removeLast(){ return remove(size - 1); } //从数组中删除元素e public void removeElement(E e){ int index = find(e); if(index != -1) remove(index); } }

     调用自定义的使用泛型后的数组方法

    public class Main {
        public static void main(String[] args) {
            Array<Integer> arr = new Array<>(20);
            for(int i = 0;i < 10; i ++)
                arr.addLast(i);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[0,1,2,3,4,5,6,7,8,9]
    
            arr.add(1,100);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[0,100,1,2,3,4,5,6,7,8,9]
    
            arr.addFirst(-1);
            System.out.println(arr);
            //Array:size= 10, capacity = 20
            //[-1,0,100,1,2,3,4,5,6,7,8,9]
    
            arr.remove(2);
            System.out.println(arr);
            //[-1,0,1,2,3,4,5,6,7,8,9]
    
            arr.removeElement(4);
            System.out.println(arr);
            //[-1,0,1,2,3,5,6,7,8,9]
    
            arr.removeFirst();
            System.out.println(arr);
            //[0,1,2,3,5,6,7,8,9]
        }
    }

     数组泛型实例

    public class Student {
        private String name;
        private int score;
    
        public Student(String studentName,int studentScore){
            name = studentName;
            score = studentScore;
        }
    
        @Override
        public String toString(){
            return String.format("Student(name: %s, score: %d)",name,score);
        }
    
        public static void main(String[] args){
            Array<Student> arr = new Array<>();
            arr.addLast(new Student("Alice",100));
            arr.addLast(new Student("Bob",66));
            arr.addLast(new Student("Charlie",88));
    
            System.out.println(arr);
            //Array:size= 3, capacity = 10
            //[Student(name: Alice, score: 100),Student(name: Bob, score: 66),Student(name: Charlie, score: 88)]
        }
    }

     3.动态数组--解决数组空间效率不高的问题

    设计了多种动态数组,比如c++中的vector,先为数组分配一个小的存储空间,将数据存储到这个空间中,当空间不够用,超出了数组的容纳极限,我们就从新分配一个空间,将原来的数据复制到这个空间中去,然后将原来定的数据空间释放,以免造成数据空间的浪费。这样的操作会导致时间复杂度的提高,所以我们应该尽量少的改变数组容量的操作。

    public class Array<E> {
        private E[] data;
        private int size;
    
        //构造函数,传入数组的容量capacity构造Array
        public Array(int capacity){
            data = (E[])new Object[capacity];
            size = 0;
        }
    
        //无参数的构造函数
        public Array(){
            this(10);
        }
    
        //获取数组中元素的个数
        public int getSize(){
            return size;
        }
    
        //获取数组的容量
        public int ggetCapacity(){
            return data.length;
        }
    
        //返回数组是否为空
        public boolean isEmpty(){
            return size == 0;
        }
    
        //向所有元素后添加一个新元素
        public void addLast(E e){
            //if(size == data.length)
            //    throw new IllegalArgumentException("AddLast failed,Array is full");
            //data[size] = e;
            //size ++;
            add(size, e);
        }
    
        //向所有元素头添加一个新元素
        public void addFirst(E e){
            add(0, e);
        }
    
        //在第index个位置插入一个新元素e
        public void add(int index,E e){
            if(index < 0 || index > size)
                throw new IllegalArgumentException("AddLast failed,Require index >=0 and index <=size");
    
            //动态增加容量
            if(size == data.length)
                resize(2 * data.length);
    
    for(int i = size -1;i >= index;i --)
                data[i + 1] = data[i];
    
            data[index] = e;
            size ++;
        }
    
        @Override
        public String toString(){
            StringBuilder res = new StringBuilder();
            res.append(String.format("Array:size= %d, capacity = %d
    ",size,data.length));
            res.append('[');
            for(int i = 0; i < size ;i ++){
                res.append(data[i]);
                if(i != size - 1)
                    res.append(",");
            }
            res.append("]");
            return res.toString();
        }
    
        //获取index索引位置的元素
        public E get(int index){
            if(index < 0 || index >= size)
                throw new IllegalArgumentException("Get Failed,Index is illegal");
            return data[index];
        }
        
    //获取最后一个位置的元素
    public E getLast(){
    return get(size - 1);
    }

    //获取第一个位置的元素
    public E getFirst(){
    return get(0);
    }
    //修改index所以位置的元素为e public void set(int index,E e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set Failed,Index is illegal"); data[index] = e; } //查找数组中是否有元素e public boolean contains(E e){ for(int i = 0;i < size;i ++){ if(data[i].equals(e)) return true; } return false; } //查找数组中元素e所在的索引,如果不存在元素e,则返回-1 public int find(E e){ for(int i = 0;i < size;i ++){ if(data[i].equals(e)) return i; } return -1; } //从数字组中删除index位置的元素,返回删除的元素 public E remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("Remove failed,Index is illegal"); E ret = data[index]; for(int i = index + 1 ;i < size;i ++) data[i - 1] = data[i]; size --; data[size] = null; //loitering objects != memory leak //动态减少容量 if(size == data.length / 2) resize(data.length / 2); return ret; } //从数组中删除第一个元素,返回删除的元素 public E removeFirst(){ return remove(0); } //从数组中删除最后一个元素,返回删除的元素 public E removeLast(){ return remove(size - 1); } //从数组中删除元素e public void removeElement(E e){ int index = find(e); if(index != -1) remove(index); }
    //重置数组容量
    private void resize(int newCapacity){ E[] newData = (E[])new Object[newCapacity]; for(int i = 0;i < size;i ++) newData[i] = data[i]; data = newData; } }

     调用自定义的动态数组方法

    //把数组码成一排进行存放
    public class Main {
        public static void main(String[] args) {
            Array<Integer> arr = new Array<>();
            for(int i = 0;i < 10; i ++)
                arr.addLast(i);
            System.out.println(arr);
            //Array:size= 10, capacity = 10
            //[0,1,2,3,4,5,6,7,8,9]
    
            arr.add(1,100);
            System.out.println(arr);
            //Array:size= 11, capacity = 20
            //[0,100,1,2,3,4,5,6,7,8,9]
    
            arr.addFirst(-1);
            System.out.println(arr);
            //Array:size= 12, capacity = 20
            //[-1,0,100,1,2,3,4,5,6,7,8,9]
    
            arr.remove(2);
            System.out.println(arr);
            //Array:size= 11, capacity = 20
            //[-1,0,1,2,3,4,5,6,7,8,9]
    
            arr.removeElement(4);
            System.out.println(arr);
            //Array:size= 10, capacity = 10
            //[-1,0,1,2,3,5,6,7,8,9]
    
            arr.removeFirst();
            System.out.println(arr);
            //Array:size= 9, capacity = 10
            //[0,1,2,3,5,6,7,8,9]
        }
    }

     4.时间复杂度分析

    分析动态数组的时间复杂度

    5. resize复杂度分析

    复杂度震荡

     修改前面的代码,解决复杂度震荡的问题

        //从数字组中删除index位置的元素,返回删除的元素
        public E remove(int index){
            if(index < 0 || index >= size)
                throw new IllegalArgumentException("Remove failed,Index is illegal");
    
            E ret = data[index];
            for(int i = index + 1 ;i < size;i ++)
                data[i - 1] = data[i];
            size --;
            data[size] = null; //loitering objects != memory leak
    
            //动态减少容量
            if(size == data.length / 4 && data.length / 2 !=0)
                resize(data.length / 2);
            return ret;
        }
  • 相关阅读:
    C#操作符??和?:
    使用Windows8开发Metro风格应用一
    使用Windows8开发Metro风格应用二
    Win8使用技巧
    详解 xls xlst xml 一
    SqlDataAdapter DataSet DataTable 详解
    DataSet 与 xml
    FileTracker : error FTK1011编译错误
    我的CHROME插件
    Komodo升级错误
  • 原文地址:https://www.cnblogs.com/zouke1220/p/9484703.html
Copyright © 2011-2022 走看看