IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 速学数据结构之结构篇(一)---List接口及相关实现 -> 正文阅读

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

结构篇(一)

1.必知基本常识

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

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

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

  1. 数组特点及优缺点

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

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

  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<E>实现List<E>接口泛型为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<arr.length;i++){     
//			data[i]=arr[i];
//			size++;
//		}   
		for(E e : arr){         //循环遍历写法二  调用函数添加
			add(e);
		}	
	}	

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

在这里插入图片描述

	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;	
	}

在这里插入图片描述

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;
	}

在这里插入图片描述

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

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 23:19:45  更:2021-07-28 23:19:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 16:39:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码