10数据结构

1.数据结构和算法的重要性

  • 算法是程序的灵魂,优秀的程序可以在海量数据计算时,依然保持高速计算
  • 一般来说,程序会使用内存计算框架和缓存技术来优化程序。核心框架的主要功能是通过算法来实现
  • 程序= 数据结构 + 算法

2.基本词汇解释和术语

  • 数据data:所有能输入到计算机中的描述客观事物的符号
  • 数据元素data element:数据的基本单位,也称结点或记录
  • 数据项data item:有独立含义的数据的最小单位,也称项
  • 数据对象data object:相同特性的数据的合集,是数据的一个子集。比如整数,学生
  • 数据结构data structure:相互存在的数据对象之间通过一种或多种特定关系组合在一起的集合。数据结构是带结构的数据元素的集合,结构就是数据元素之间存在的关系。

3.数据的逻辑结构

  • 线性结构:数据元素之间存在一对一的关系。常见的线性结构有数组,队列,链表,栈。线性结构又分为
  1. 顺序的 (存储结构和逻辑结构一致)
  2. 链式的(物理结构和逻辑结构不一致,数据元素存放不连续)
  • 非线性结构:数据元素之间存在多重关系。常见的非线性结构有二维数组,多维数组,树,图。

4.数据的存储结构

存储结构就是物理结构,数据元素以及相互的关系在计算机中存储的方式(数据元素之间的关系在存储中的显示)

顺序存储结构-- 借助于元素在存储容器中的相对位置来表示元素间的逻辑关系

链式存储结构--借助于元素存储地址的指针表示元素间的逻辑关系

5.栈

特点:栈只能在一端(栈顶)操作。先进后出,后进先出。

应用:(1)计算进制转换 (2)括号检验匹配 (3)迷宫求解 (4)表达式求值/中缀后缀 (5)递归(6)Java方法调用和返回

底层实现:数组

常用的方法:(规定这些方法的接口也称为栈的规范)

1.入栈 2.出栈 3.判断栈是否为空 4.判断栈是否已满 5.返回栈顶元素 6.返回元素在栈中的位置 7.返回栈的实际长度 8.返回栈的容量 9.打印栈

public interface IStack {
    //1 入栈
     boolean  push(Object obj);
    //    2 出栈
    Object pop();
    //    3 判断栈是否为空
     boolean isEmpty();
    //    4 判断栈是否已满
     boolean isFull();
    //    5 返回栈顶元素
     Object peek();
    //    6 返回元素在栈中的位置
    int getIndex(Object obj);
    //    7 返回栈的实际长度
    int size();
    //    8 返回栈的容量
    int getStatckSize();
    //    9  打印栈
    void  display();
}

返回栈中指定元素的位置:递归

public int getElement(Stack<Integer> stack, int position)
    {
        int result = stack.pop();
        if (stack.size() == position)
        {
//            stack.push(result);
            return result;
        }else {
            int element = getElement(stack, position);
            stack.push(element);
            return element;
        }
    }

栈的递归实现

public class MyStack implements IStack {
    private static final int MAX_SIZE = 5;
    private static Object[] data = new Object[MAX_SIZE];
    private static int top = -1;//[0,4],表示当前存放的位置

    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        myStack.push(4);
        myStack.pop();
        myStack.pop();
        System.out.println("size:"+myStack.size());
        myStack.display();
        myStack.push(5);
        myStack.push(6);
        myStack.display();
        System.out.println("size:"+myStack.size());
        System.out.println("指定下标的元素为:"+myStack.getIndex(2));
        System.out.println("指定下标的元素为:"+myStack.getIndex(6));
        myStack.display();
    }
    @Override
    public boolean push(Object obj) {
        if (isFull()) return false;
        data[++top] = obj;
        return true;
    }

    @Override
    public Object pop() {
        if (isEmpty()) return null;
        Object res = data[top--];
        return res;
    }

    @Override
    public boolean isEmpty() {
        return top == -1;
    }

    @Override
    public boolean isFull() {
        return top >= MAX_SIZE - 1;
    }

    @Override
    public Object peek() {
        if (isEmpty()) return null;
        return data[top];
    }
    @Override
    public int getIndex(Object obj) {
        if(size()==0) return -1;
        Object o = pop();
        if(o!=obj) {
            int idx =  getIndex(obj);
            push(o);
            return idx;
        }else{
            push(o);
            return size()-1;
        }
    }
    @Override
    public int size() {
        return top+1;
    }

    @Override
    public int getStackSize() {
        return MAX_SIZE;
    }

    @Override
    public void display() {
        System.out.print("当前栈内元素为:");
        dfs();
        System.out.println();
    }
    public void dfs(){
        if(size()==0) return ;
        Object o =pop();
        dfs();
        push(o);
        System.out.print(o+" ");
    }

    @Override
    public Object getObjectByIndex(int index) {
        Object res = pop();
        if(res ==null) return null;
        if(size()!=index){
            Object element = getObjectByIndex(index);
            push(element);
            return element;
        }
        else return res;
    }



}

 

6.队列

队列的特点:从队列头出,从队列末入。先入先出,后入后出。

底层:数组

假溢出:队列元素出队之后,队列假满,其实队列前面有空位置

解决假溢出:循环队列

判断循环队列的空和满:

  1. 设置标志flag,初始时flag=0,每当元素入队,设flag=1,每当元素出队,设flag为0。队列判断为空:flag==0&&front==rear。队列判断为满:flag==1&&front==rear。
  2. 预留一个元素的存储空间。此时判断队列为空:rear==front,判断队列为满:(rear+1)%MAX_SIZE == front
  3. 设置一个计数器count,表示队列中元素个数。队列为空:count==0,队列为满:count==MAX_SIZE。

循环队列入队:rear= (rear+1)%MAX_SIZE

循环队列出队:front=(front+1)%MAX_SIZE

public interface IQueue {
    //入队
     void  append(Object obj);
    // 出队
    Object delete();
    //获得对头元素
    Object getFront();
    // 判断队列是否为空
    boolean isEmpty();
}

 

posted @ 2021-07-26 08:55  岛boki  阅读(163)  评论(0编辑  收藏  举报