时间复杂度
时间复杂度比较:
时间复杂度基本计算规则
- 基本操作,即只有常数项,认为其时间复杂度为O(1)
- 顺序结构,时间复杂度按加法进行计算
- 循环结构,时间复杂度按乘法进行计算
- 分支结构,时间复杂度取最大值
判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
物理结构
- 顺序存储结构:是吧数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。(线性表)
- 链式存储结构:是把数据结构存放在任意的存储单元里,这组存储单元可以连续,也可以不连续。
逻辑结构
-
线性结构
-
树结构
a. 二叉树:一对二。
定义: 二叉树(Binary Tree)是每个节点最多有两个子树的树结构
b. 树状:一对多
图结构
- 有向图
- 无向图
- 图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成
接口定义
- List接口
package 算法.p1.接口;
import java.util.Comparator;
public interface List<E> extends Iterable<E>{
public void add(E element);
//指定脚标出添加
public void add(int index, E element);
public E remove(int index);
public void remove(E element);
//获取指定角标处的元素
public E get(int index);
public E set(int index,E element);
//元素的个数
public int size();
//查看元素第一次出现的
public int indexOf(E element);
//判断是福哦包含
public boolean contains(E element);
// 判断是否为空
public boolean isEmpty();
public boolean equals(Object o);
//清空
public void clear();
//按照比较器进行排序
public void sort(Comparator<E> c);
public List<E> subList(int fromIndex, int toIndex);
}
- Stack接口
package 算法.p1.接口;
public interface Stack<E> extends Iterable<E>{
public int size();
public boolean isEmpty();
public void push(E element);
public E pop();
public E peek();
public void clear();
}
接口实现
- List
package 算法.p2.线性结构;
import 算法.p1.接口.List;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Comparator;
import java.util.Iterator;
//自定义的线性表的顺序存储方式
public class ArrayList<E> implements List<E> {
//数组的容器 data.length 指的就是当前数组的容量
private E[] data;
//元素的个数 size == 0 线性表为空 size == data.length 线性表满了
//size 新元素默认尾部添加时要去的角标
private int size;
//默认容量
private static int DEFAULT_CAPACITY = 10;
//创建一个默认容量为10的线性表
public ArrayList() {
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
//创建一个指定容量的线性表
public ArrayList(int capacity) {
if (capacity <= 0) {
throw new IllegalArgumentException("capacity must > 0");
}
DEFAULT_CAPACITY = capacity;
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
//传入一个数组 将该数组封装成为一个线性表
public ArrayList(E[] arr) {
if (arr == null || arr.length == 0) {
throw new IllegalArgumentException("arr can not be null");
}
data = (E[]) new Object[DEFAULT_CAPACITY];
for (int i = 0; i < arr.length; i++) {
add(arr[i]);
}
}
@Override
public void add(E element) {
add(size, element);
}
@Override
public void add(int index, E element) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("add index out of range");
}
//判断线性表是否是满状态
if (size == data.length) {
resize(2 * data.length);
}
//向后移动元素
for (int i = size - 1; i >= index; i--) {
data[i + 1] = data[i];
}
//将新元素插入到指定位置
data[index] = element;
size++;
}
//扩容/缩容 操作 不应该向外界提供
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
for (int i = 0; i < size; i++) {
newData[i] = data[i];
}
data = newData;
}
@Override
public void remove(E element) { //删除指定元素 只删除一次 && 删除所有的指定元素
int index = indexOf(element);
if (index != -1) {
remove(index);
}
}
@Override
public E remove(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("remove index out of range");
}
//先保存要删除的值
E ret = data[index];
//移动元素
for (int i = index + 1; i < size; i++) {
data[i - 1] = data[i];
}
size--;
//什么时候缩容
//1.有效元素是容量的1/4
//2.当前容量不得小于等于默认容量
if (size == data.length / 4 && data.length > DEFAULT_CAPACITY) {
resize(data.length / 2);
}
return ret;
}
@Override
public E get(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("get index out of range");
}
return data[index];
}
@Override
public E set(int index, E element) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("set index out of range");
}
E ret = data[index];
data[index] = element;
return ret;
}
@Override
public int size() {
return size;
}
//额外添加一个函数 获取线性表中那个数组的容量
private int getCapacity() {
return data.length;
}
@Override
public int indexOf(E element) {
/*
== 比的是啥?主要看等号的两边是啥
== 两边是基本数据类型的话 比的是值
byte short int long
float double
char boolean
== 两边是引用数据类型的话 比的是地址
数组 字符串 其他的类对象
*/
for (int i = 0; i < size; i++) {
if (data[i].equals(element)) {
return i;
}
}
return -1;
}
@Override
public boolean contains(E element) {
return indexOf(element) != -1;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
data = (E[]) new Object[DEFAULT_CAPACITY];
size = 0;
}
@Override
public void sort(Comparator<E> c) {
if (c == null) {
throw new IllegalArgumentException("comparator can not be null");
}
for (int i = 1; i < size; i++) {
E e = data[i];
int j = 0;
for (j = i; j > 0 && c.compare(data[j - 1], e) > 0; j--) {
data[j] = data[j - 1];
}
data[j] = e;
}
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
if (fromIndex < 0 || toIndex >= size || fromIndex > toIndex) {
throw new IllegalArgumentException("must 0 <= fromIndex <= toIndex <= size - 1");
}
ArrayList<E> list = new ArrayList<>();
for (int i = fromIndex; i <= toIndex; i++) {
list.add(data[i]);
}
return list;
}
@Override
public boolean equals(Object o) {
//1.判空
if (o == null) {
return false;
}
//2.判自己
if (this == o) {
return true;
}
//3.判类型
if (o instanceof ArrayList) {
//4.按照自己的逻辑进行比较
ArrayList<E> other = (ArrayList<E>) o;
//5.先比有效元素的个数
if (size != other.size) {
return false;
}
//6.有效元素个数相等的情况下 逐个比较元素
for (int i = 0; i < size; i++) {
if (!data[i].equals(other.data[i])) {
return false;
}
}
return true;
}
return false;
}
/*
[1, 2, 3, 4, 5, 6]
[]
Arrays.toString(arr);
*/
@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(',');
sb.append(' ');
}
}
}
return sb.toString();
}
//获取当前这个数据结构/容器 的 迭代器
//通过迭代器对象 更方便挨个取出每一个元素
//同时 实现了Iterable 可以让当前的数据结构/容器 被foreach循环遍历
@Override
public Iterator<E> iterator() {
return new ArrayListIterator();
}
//创建一个属于ArrayList的迭代器
class ArrayListIterator implements Iterator<E> {
private int cur = 0;
@Override
public boolean hasNext() {//判断是否有下一个元素
return cur < size;
}
@Override
public E next() {//如果有下一个元素 则把当前元素返回 并移至到下一个元素
return data[cur++];
}
}
}
- Stack
package 算法.p2.线性结构;
import 算法.p1.接口.Stack;
import java.util.Iterator;
public class ArrayStack<E> implements Stack<E> {
private ArrayList<E> list;
public ArrayStack() {
list = new ArrayList<>();
}
public ArrayStack(int capacity) {
list = new ArrayList<>(capacity);
}
@Override
public int size() {
return list.size();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public void push(E element) {
list.add(element);
}
@Override
public E pop() {
return list.remove(list.size() - 1);
}
@Override
public E peek() {
return list.get(list.size() - 1);
}
@Override
public void clear() {
list.clear();
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
if (this == o) {
return true;
}
if (o instanceof ArrayStack) {
ArrayStack other = (ArrayStack) o;
return this.list.equals(other.list);
}
return false;
}
}
栈
- push() 入栈
- pop() 出栈
- size() 栈大小
- peek() 栈顶
- clear() 清除
- equals 比较
- iterator 迭代
未完之后补