速学数据结构之结构篇(一)---List接口及相关实现

结构篇一

  • 结构篇(一)
    • 1.必知基本常识
      • 1.计算机中的数据存储方式
    • 2.手写List接口
    • 3.通过LIst接口手写动态数组ArrayList
      • 1. 定义常量并初始化
      • 2. 实现LISt接口的方法-----------增
      • 3. 实现LISt接口的方法-----------删
      • 4. 实现LISt接口的方法-----------改,查
      • 5.手撕size,clear,isEmpty,indexof,contains。
      • 5.sort(插入)、iterator
      • 6.toString,,,,equals
      • 7.测试,与结果
      • 代码分享

结构篇(一)

1.必知基本常识

1.计算机中的数据存储方式

  1. 顺序存储结构(数组
    在这里插入图片描述

这种为顺序存储结构,开辟出一块同等大小的连续空间。通常指数组。

  1. 数组特点及优缺点

开辟的空间大小固定,一旦开辟不可更改
只能存储同一类型的数据
每个元素的空间地址都是连续的
通过下标的方式访问数组,访问速度快

(可能容量不够)
(增删元素慢)
方法单一,只有length属性

  1. 链式存储结构
    速学数据结构之结构篇(一)---List接口及相关实现_第1张图片

这种为链式存储,为随机空间,之间相连的空间被称为节点,每个节点分为两部分,一部分用于存储数据,一部分用于存储下一个数据的地址,通常被称为指向下一个地址。节点在空间内随机分布,没有规律。
二叉树能通过这两种方式进行存储

  1. 实现目标:通过对数组进行封装,实现动态数组ArrayList。

2.手写List接口

  1. 我们需要先定义好接口,接口是一个类的规范,List将要实现的功能主要为:增删改查

Iterable迭代器接口 使之可迭代遍历
Comparator比较器,是自身与别的对象作比较

public interface List<E> extends Iterable<E> {
     
    /**
     * 在线性结构的末尾添加一个元素element
     * */
    public void add(E element);
    /**
     * 在线性结构指定角标index处添加一个元素element
     * */
    public void add(int index,E element);
    /**
     * 在线性结构中删除指定元素element
     * */
    public void remove(E element);
    /**
     * 在线性结构中删除指定角标index处的元素,并返回
     * */
    public E remove(int index);
    /**
     * 在线性结构中获取指定角标处index的元素
     * */
    public E get(int index);
    /**
     * 在线性结构中修改指定角标处index的元素为新元素element
     * */
    public E set(int index,E element);
    /**
     * 获取线性结构中有效元素的个数
     * */
    public int size();
    /**
     * 获取指定元素element在线性结构中的角标
     * */
    public int indexOf(E element);
    /**
     * 查看线性表中是否包含指定元素element
     * */
    public boolean contains(E element);
    /**
     * 查看线性结构是否为空
     * */
    public boolean isEmpty();
    /**
     * 清空线性结构
     * */
    public void clear();
    /**
     * 对线性结构按照比较器comparator的定义来进行排序
     * */
    public void sort(Comparator<E> comparator);
    /**
     * 获取线性结构中从指定fromIndex角标开始到toIndex角标结尾的所有元素
     * (0 <= fromIndex < toIndex < size)
     * [fromIndex,toIndex)
     * */
    public List<E> sublist(int fromIndex,int toIndex);
}

3.通过LIst接口手写动态数组ArrayList

ArrayList实现List接口泛型为E

1. 定义常量并初始化

	private int size;//有效元素个数
	private E[] data;  //我们用数组实现  底层为数组
	private final static int DEFULT_CAPACITY = 10;  //默认容量
	//初始化  
		public ArrayList(){
     
		this(DEFULT_CAPACITY);
	}
	//指定容量
	public  ArrayList(int capacity) {
     
		if (capacity <= 0) {
     
			throw new IllegalArgumentException("capacity must >0");
		}
		data = (E[]) new Object[capacity];
		size = 0;
	}
	//传入数组
	public ArrayList(E[] arr){
     
		if (arr == null) {
     
			throw new IllegalArgumentException("arr cannot be empty");
		}
		data=(E[])new Object[arr.length];
		size=0;   //初始化有效长度
//		for(int i=0;i
//			data[i]=arr[i];
//			size++;
//		}   
		for(E e : arr){
              //循环遍历写法二  调用函数添加
			add(e);
		}	
	}	

2. 实现LISt接口的方法-----------增

速学数据结构之结构篇(一)---List接口及相关实现_第2张图片

	public void add(E element) {
     
		add(size,element);  //调用指定位置添加元素

	}
	
	@Override
	public void add(int index, E element) {
     
		if (index<0 || index >size) {
         //判断插入下标是否合法
			throw new IndexOutOfBoundsException("Array index out of bounds ");
		}
		if (size  == data.length) {
       //如果满了就扩容
			resize(data.length*2);
		}
		for(int i=size;i>index;i--){
       //把前一个元素向后移一位
			data[i]=data[i-1];
		}
		data[index]=element;  //赋值
		size++;  //长度加1
		
	}

	private void resize(int capacity) {
       //扩容 
		E[] newdata=(E[]) new Object[capacity];
		for(int i=0;i<data.length;i++){
     
			newdata[i]=data[i];
		}
		data=newdata;	
	}

速学数据结构之结构篇(一)---List接口及相关实现_第3张图片

3. 实现LISt接口的方法-----------删

	@Override
	public void remove(E element) {
     
		int index; //定义个下标接收查找元素的下标
		while ((index=indexof(element))!=-1) {
      //如果找到元素  ---返回值不等于-1
			remove(index);  //通过找到的元素删除下标
		}
	}
	@Override
	public E remove(int index) {
     
		if (index<0 || index >=size) {
         //判断插入下标是否合法
			throw new IndexOutOfBoundsException("Array index out of bounds ");
		}
		E ret=data[index];//接收删除的元素
		for(int i=index;i<size-2;i--){
       //循环遍历把index之后的元素前移一位
			data[i]=data[i+1];
		}
		size--;
		if (size== data.length/4 && size >DEFULT_CAPACITY) {
     
			resize(data.length/2);
		}
		return ret;
	}

速学数据结构之结构篇(一)---List接口及相关实现_第4张图片

4. 实现LISt接口的方法-----------改,查

@Override
	public E set(int index, E element) {
     
		if (index<0 || index >=size) {
         //判断插入下标是否合法
			throw new IndexOutOfBoundsException("Array index out of bounds ");
		}
		E ret=data[index];  //获取值之后再做更改
		data[index]=element;
		return ret;  
	}

	@Override
	public E get(int index) {
     
		if (index<0 || index >=size) {
         //判断插入下标是否合法
			throw new IndexOutOfBoundsException("Array index out of bounds ");
		}
		return data[index];  //直接返回获取到的值
	}

5.手撕size,clear,isEmpty,indexof,contains。

	@Override
	public int size() {
     
		return size; //直接返回长度
	}
	@Override
	public void clear() {
     
		E[] newdata=(E[])new Object[DEFULT_CAPACITY];  //创建个新数组
		size=0;//有效长度清空
		data=newdata;//data重新指向新数组
	}
	@Override
	public boolean isEmpty() {
     
		return size==0;  //长度是否为0
	}
	@Override
	public int indexof(E element) {
     
		for(int i=0;i<data.length;i++){
     
			if(data[i]==element){
       //循环查找 如果找到元素则返回下标 
				return i;  //返回下标
			}
		}
		return -1;  //如果没找到就返回-1
	}
	@Override
	public boolean contains(E element) {
     
		return indexof(element) != -1;  //找到为下标>=0  找不到为-1
	}

5.sort(插入)、iterator

	@Override
	public void sort(Comparator<E> comparator) {
     
		if(comparator ==null){
     
			throw new IllegalArgumentException("comparator cannot be null");
		}
		for(int i=1;i<size;i++){
     
			E e=data[i];
			int j;
			for(j=i;j>0 && comparator.compare(data[j-1], e) != -1;j--){
     
				data[j]=data[j-1];
			}
			data[j]=e;
		}
	}

  //返回迭代器对象
  @Override
  public Iterator<E> iterator() {
     
      return new ArrayListIterator();
  }

  private class ArrayListIterator implements Iterator<E> {
     
      private int cur = 0;
      @Override
      public boolean hasNext() {
     
          return cur < size;
      }

      @Override
      public E next() {
     
          return data[cur++];
      }
  }

6.toString,equals

	@Override
	public String toString() {
     
		StringBuilder sb = new StringBuilder();  //用于存储输出内容
		sb.append('[');  //起始左括号
		if (isEmpty()) {
       //如果为空就给右括号结束
			sb.append(']');
		} else {
     
			for (int i = 0; i < size; i++)  //循环遍历输出
			{
     
				sb.append(data[i]);  //不是最后一位数就以逗号隔开
				if (i < size - 1) {
     
					sb.append(',');
				} else {
     
					sb.append(']');  //最后一位数就以括号结尾
				}
			}
		}
		return sb.toString();  //输出
	}
	
	@Override
	public boolean equals(Object obj) {
     
		if(obj ==null) return false;  //是否为空
		if(obj==this) return true;		//是否与自己比较
		if (obj instanceof ArrayList) {
      //是不是通类型
			ArrayList other=(ArrayList) obj;  
			if (this.size == other.size) {
      //长度是否相同
				for(int i=0;i<size;i++){
      //循环遍历
					if (!this.data[i].equals(other.data[i])) {
     
						return false;   //对应值不同返回false;
					}
				}
				return true;
			}else {
     
				return false;
			}
		}else {
     
			return false;

		}
	}

7.测试,与结果

package interfs;



import java.util.Comparator;
import java.util.Iterator;


public class TesArrayList {
     
    public static void main(String[] args) {
     
        ArrayList<Integer> list1 = new ArrayList<>();
        System.out.println(list1);
        for (int i = 1; i <= 12; i++) {
     
            list1.add(i);
        }
        System.out.println(list1);
        list1.add(8,13);
        System.out.println(list1);
        list1.remove(3);
        System.out.println(list1);
        list1.sort(new Comparator<Integer>() {
     
            @Override
            public int compare(Integer o1, Integer o2) {
     
                return o2 - o1;
            }
        });
        System.out.println(list1);
        for(Integer e : list1) {
     
            System.out.println(e);
        }
        Iterator<Integer> it = list1.iterator();
        while (it.hasNext()) {
     
            System.out.println(it.next());
        }
        ArrayList<Integer> list2 = new ArrayList<>(100);
        ArrayList<Integer> list3 = new ArrayList<>(1000);
        for (int i = 1; i <= 3; i++) {
     
            list2.add(i);
            list3.add(i);
        }
        System.out.println(list2.equals(list3));

        ArrayList<Person> list4 = new ArrayList<>();
        list4.add(new Person("lili",18));
        list4.add(new Person("hanmeimei",19));
        list4.add(new Person("lilei",20));
        list4.add(new Person("naruto",16));
        list4.add(new Person("sasike",1));
        list4.add(new Person("hinata",9));
        list4.add(new Person("aliaba",30));
        list4.add(new Person("babaaiwo",32));
        System.out.println(list4);
        list4.sort(new Comparator<Person>() {
     
            @Override
            public int compare(Person o1, Person o2) {
     
                //return o1.age - o2.age;
                return o1.name.compareTo(o2.name);
            }
        });
        System.out.println(list4);
    }
}
class Person {
     
    String name;
    int age;
    public Person(String name ,int age) {
     
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
     
        return "我是" + name + ",今年" + age + "岁";
    }

    @Override
    public boolean equals(Object obj) {
     
        if (obj == null) {
     
            return false;
        }
        if (obj == this) {
     
            return true;
        }
        if (obj instanceof Person) {
     
            Person other = (Person) obj;
            return other.age == this.age && other.name.equals(this.name);
        } else {
     
            return false;
        }
    }
}
//结果
[]
[1,2,3,4,5,6,7,8,9,10,11,12]
[1,2,3,4,5,6,7,8,13,9,10,11,12]
[1,2,3,5,6,7,8,13,9,10,11,11]
[11,11,10,9,13,8,7,6,5,3,2,1]
11
11
10
9
13
8
7
6
5
3
2
1
11
11
10
9
13
8
7
6
5
3
2
1
true
[我是lili,今年18,我是hanmeimei,今年19,我是lilei,今年20,我是naruto,今年16,我是sasike,今年1,我是hinata,今年9,我是aliaba,今年30,我是babaaiwo,今年32]
[我是aliaba,今年30,我是babaaiwo,今年32,我是hinata,今年9,我是sasike,今年1,我是naruto,今年16,我是lilei,今年20,我是hanmeimei,今年19,我是lili,今年18]

代码分享

链接: 代码文件------密码:86mj

你可能感兴趣的:(数据结构,数据结构,arraylist)