数据结构01

数据结构

逻辑结构

线性结构:元素之间一对一关系

树形结构:元素之间一对多的层次关系

图形结构:元素之间多对多的关系

物理结构

顺序存储结构:开辟一组连续的空间存储数据 用数组实现 内存利用率低 方便查找

链式存储结构:开辟一组随机的空间存储数据 用节点实现 内存利用率高 不方便查找

时间复杂度

分析代码 写出复杂度式子 去掉常数项 只保留最高项 且最高项倍数变为1

线性表

定义:零个或多个元素的有限序列

​ a i-1是 a的前驱 a i+1是a的后继

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 void remove(E element);
    //删除指定角标处元素 返回原先的值
    public E remove(int index);
    //获取指定角标处元素
    public E get(int index);
    //修改指定角标index值element 返回原先的值
    public E set(int index, E element);
    //获取线性表中元素个数
    public int size();
    //查看元素第一次出现的角标位置   从左到右
    public int indecOf(E element);
    //判断是否包含元素
    public boolean contains(E element);
    //判断线性表是否为空
    public boolean isEmpty();
    //清空线性表
    public void clear();
    //按照比较器的内容排序
    public void sort(Comparator<E> c);
    //获取子线性表 元线性表中[fromIndex,toIndex]这部分
    public List<E> subList(int fromIndex,int toIndex);

    public  boolean equals(Object o);


}

package p2.线性结构;

import p1.接口.List;

import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;

//自定义线性顺序存储方式
public class ArrayList<E> implements List<E> {
    //定义数组容器 data.le当前数组容量ngth 指
    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){
            //IllegalArgumentException java自带参数异常
            throw new IllegalArgumentException("capacity必须大于0");
        }
        DEFAULT_CAPACITY = capacity;
        data = (E[]) new Object[DEFAULT_CAPACITY];
        size = 0;
    }
    //指定数组的构造函数:传入一个数组 将该数组封装成一个线性表
    //[1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
    public ArrayList(E[] arr){
        if(arr == null || arr.length == 0){
            throw new IllegalArgumentException("arr 不能为空");
        }
        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 越界");
        }
        //线性表判满
        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 = indecOf(element);
        if(index != -1){
            remove(index);
        }
    }

    @Override
    public E remove(int index) {
        //判空
        if(index < 0 || index >=size){
            throw new IllegalArgumentException("remove index 越界");
        }

        //先保存要删的值 最后返回
        E ret = data[index];
        //移动元素
        for(int i = index+1;i < size-1;i++){
            data[i-1] = data[i];
        }
        size--;
        //缩容
        // 1、有效元素是当前元素个数的四分之一
        //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 越界");
        }
        return data[index];
    }

    @Override
    public E set(int index, E element) {
        if(index < 0 || index >=size){
            throw new IllegalArgumentException("set index 越界");
        }
        E ret = data[index];
        data[index] = element;
        return ret;

    }

    @Override
    public int size() {
        return size;
    }
    //额外添加一个函数 获取线性表数组容量
    private int getCapacity(){
        return data.length;
    }

    @Override
    // == 等号两边是啥 基本类型->值 引用类型->比的是地址
    public int indecOf(E element) {
        for (int i = 0;i < size;i++){
            if(data[i].equals(element) ){
                return  i;
            }
        }
        return -1;
    }

    @Override
    public boolean contains(E element) {
        return indecOf(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 不能为空");
        }
        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) {
        //判空
        if (o == null){
            return false;
        }
        //判自己
        if (this == o){
            return true;
        }
        //判类型
        if (o instanceof ArrayList){
            //按照自己的逻辑比较
            ArrayList<E> other = (ArrayList<E>)o;
            //先比较有效元素个数
            if (size != other.size){
                return false;
            }
            //如果元素个数相等 再逐个元素比较
            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 可以让当前数据结构/容器
    @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++];
        }
    }

}

package p0.测试;

import p2.线性结构.ArrayList;

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

public class TestArrayList {
    public static void main(String[] args){
        ArrayList<Integer> list = new ArrayList<>();
        System.out.println(list);
        Random random = new Random();
        for (int i = 0;i < 10;i++){
            list.add(random.nextInt(100));
        }
        System.out.println(list);

        for (int i = 0; i < 10;i++){
            list.add(0,i);
        }
        System.out.println(list);

        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        System.out.println(list);

        for(Integer num : list){
            System.out.println(num);
        }

        Iterator<Integer> it = list.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
    }
}

栈是限定仅在表尾进行插入删除操作

允许插入删除的一端叫栈顶 另一端叫栈底

不含任何元素的栈叫空栈

栈又叫后进先出的线性表

站本身是一个线性表,其数据元素具有线性关系,是特殊的线性表

栈的插入叫入栈 删除叫弹栈

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();

}

package p2.线性结构;

import p1.接口.Stack;

import java.util.Iterator;
import java.util.Objects;

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

package p0.测试;

import p2.线性结构.ArrayStack;

public class TestArrayStack {
    public static void main(String[] args) {
        ArrayStack<Integer> stack01 = new ArrayStack<>();
        ArrayStack<Integer> stack02 = new ArrayStack<>(15);
        for (int i = 1;i <= 12;i++){
            stack01.push(i);
            stack02.push(i);
        }
        System.out.println(stack01);
        System.out.println(stack02);
        System.out.println(stack01.equals(stack02));

        System.out.println(stack01.pop());
        System.out.println(stack01);
        System.out.println(stack01.peek());
    }
}

中缀表达式

是一个通用的逻辑公式表示方法 操作符是以中缀形式处于操作数的中间如(3+4)

与前缀表达式(+34)或后缀表达式(43+)相比中缀表达式不易被计算机解析

但仍被许多程序语言使用

package p2.线性结构;
//中缀表达式计算器
public class InfixCalculator {
    public static void main(String[] args) {
        String expression = "(10+20/2*3)/2+8";
        try{
            int result = evaluateExpression(expression);
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("Wrong expression:" + expression);
        }
    }

    private static int evaluateExpression(String expression) {
        //需要两个辅助栈
        ArrayStack<Character> operatorStack = new ArrayStack<>();
        ArrayStack<Integer> numberStack = new ArrayStack<>();
        //格式化表达式
        expression = insertBlanks(expression);
        String[] tokens = expression.split(" ");
        for (String token : tokens){
            //过滤空串
            if(token.length() == 0){
                continue;
                //遍历 + -号
                //如果之前是+-*/需要弹栈计算
            }else if(token.equals("+") || token.equals("-")){
                while (!operatorStack.isEmpty() && (operatorStack.peek() == '+' || operatorStack.peek() == '-' || operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
                    //如果是之前别的+- 需要弹栈计算
                    processAnOperator(numberStack,operatorStack);
                }
                //入股操作符栈为空 或不为空但栈顶为(
                operatorStack.push(token.charAt(0));
                //遍历 */
            }else if(token.equals("*") || token.equals("/")){
                while (!operatorStack.isEmpty() && (operatorStack.peek() == '*' || operatorStack.peek() == '/' )){
                    //如果是之前别的*/ 需要弹栈计算
                    processAnOperator(numberStack,operatorStack);
                }
                //入股操作符栈为空 或不为空但栈顶为(
                operatorStack.push(token.charAt(0));
                //遍历(
        }else if(token.equals("(")){
                operatorStack.push(token.charAt(0));
                //遍历到)
            }else if(token.equals(")")){
                //操作符栈不是( 全部弹栈计算
                while (operatorStack.peek() != '('){
                    processAnOperator(numberStack,operatorStack);
                }
                //去掉左括号
                operatorStack.pop();
                //遍历到数字
            }else{
                numberStack.push(new Integer(token));
            }
        }
        //处理最后操作符
        while (!operatorStack.isEmpty()){
            processAnOperator(numberStack,operatorStack);
        }
        return numberStack.pop();
    }
    //操作符栈第一个元素 数字栈弹栈两个数字 计算 并入栈数字栈
    private static void processAnOperator(ArrayStack<Integer> numberStack, ArrayStack<Character> operatorStack) {
        char op = operatorStack.pop();
        int num1 = numberStack.pop();
        int num2 = numberStack.pop();
        //num2 op num1
        if(op == '+'){
            numberStack.push(num2 + num1);
        }else if(op == '-'){
            numberStack.push(num2 - num1);
        }else if(op == '*'){
            numberStack.push(num2 * num1);
        }else{
            numberStack.push(num2 / num1);
        }
    }

    //对原表格式化处理 给非数字加空格;
    private static String insertBlanks(String expression) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < expression.length(); i++) {
            char c = expression.charAt(i);
            if (c == '(' || c == ')' || c == '+' || c == '-' || c == '*' || c == '/') {
                sb.append(' ');
                sb.append(c);
                sb.append(' ');
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值