简单数据结构概述

数据结构概述

数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。

数据结构分类

物理结构

数组:数组用来存放相同类型的数据,数组在计算机中内存的开辟是连续的,而且数组一旦被定义,它的大小是不能再改变了,除非重新开辟一个更大的数组。

链表:与数组不同,链表在计算机中内存的开辟是跳跃的,它有一个指向后继的引用(双向链表还有一个指向前驱的引用),所以只要能够获取链表的头,那么剩下的数据就能轻松获取了。

数组和链表的相同与不同:
1.数组和链表都是计算机内存中真实存在的数据组织方式,所以称为物理结构。
2.数组和链表在逻辑上都可以成环,数组成环依靠下标+1模数组长度,让下标每到达数组长度-1时变为0,链表依靠循环链表。
3.数组由于有索引存在,所以便于读操作,但是不适合增删操作,因为要保持有序,必须把元素移位,这很耗时。链表由于有指向下一个元素的引用存在,所以适合增删操作,只需要更改引用,但是不适合读操作,因为无法快速定位到需要读的元素。

逻辑结构

逻辑结构分为线性表和非线性表,简单数据结构先介绍线性表,非线性表之后再述。

线性表

栈:栈是只能在一端加入元素和删除元素,加入元素称为入栈,删除元素称为出栈,最先入栈的元素被压入栈底,最后入栈的元素在栈顶,所以最先入栈的元素最后出栈,所以栈是先进后出。

队列:队列可以在一端加入元素,另一端删除元素,加入元素称为入队,删除元素称为出队,最先入队的元素在队头,最后入队的元素在队尾,所以最先入队的元素最先出队,所以队列是先进先出。

栈和队列都可以使用数组和链表实现。

非线性表

栈和队列的实现

数组实现一个栈

public class OrderStack<E> {
    //指向栈顶的引用
    private int top;
    //数组 存放元素
    private E[] stackArrays;

    public OrderStack() {
        this(5);
    }

    @SuppressWarnings("unchecked")
    private OrderStack(int capacity) {
        this.top = 0;//栈顶 从0开始
        this.stackArrays = (E[]) new Object[capacity];
    }

    public boolean isFull() {
        return top == stackArrays.length;
    }

    //入栈
    public void push(E val) {
        //判满
        if (isFull()) {
            stackArrays = Arrays.copyOf(stackArrays, stackArrays.length * 2);
        }
        stackArrays[top++] = val;
    }

    public boolean isEmpty() {
        return top == 0;
    }

    //出栈 返回栈顶元素并且删除
    public E pop() {
        //判空
        if (isEmpty()) {
            throw new UnsupportedOperationException("the stack is empty");
        }
        E result = stackArrays[top - 1];
        stackArrays[top - 1] = null;
        top--;
        return result;
    }

    //获取栈顶元素
    public E peek() {
        //判空
        if (isEmpty()) {
            throw new UnsupportedOperationException("the stack is empty");
        }
        return stackArrays[top - 1];
    }
}

链表实现一个栈

public class LinkedListStack<E>{
    private Node<E> top;

    class Node<E>{
        protected E data;
        protected Node<E> next;

        Node(E data){
            this.data = data;
            this.next = null;
        }
    }

    @SuppressWarnings("unchecked")
    public LinkedListStack(){
        top = new Node<E>((E)new Object());//头引用,位于栈底
    }

    //入栈 头插
    public void push(E val){
        //创建一个新节点
        Node<E> newNode = new Node<>(val);
        newNode.next = top.next;
        top.next = newNode;
    }

    //出栈 获取栈顶元素并删除
    public E pop(){
        if(top.next == null)  return null;
        E result = top.next.data;
        top.next = top.next.next;
        return result;
    }

    //获取栈顶元素
    public E peek(){
        if(top.next == null)  return null;
        return top.next.data;
    }
}

数组实现一个队列

public class ArrayQueue<E>{
    private int front;//队头  删除元素
    private int rear;//队尾  添加元素
    private E[] elements;
    private static int defaultSize = 5;

    public ArrayQueue(){
        this(defaultSize);
    }

    @SuppressWarnings("unchecked")
    public ArrayQueue(int size){
        elements = (E[])new Object[size];
        front = 0;
        rear = 0;
    }
    
    //判空
    public boolean isEmpty(){
        return front == rear;
    }
    //判满
    public boolean isFull(){
        return rear == elements.length;
    }
    //入队
    public void push(E value){
        if(isFull()){
            elements = Arrays.copyOf(elements,elements.length<<1);
        }
        elements[rear++] = value;
    }
    //出队
    public E pop(){
        if(isEmpty()){
            return null;
        }
        E tmp = elements[front];
        System.arraycopy(elements, 1, elements, 0, rear - front);
        rear--;
        return tmp;
    }
}

链表实现一个队列

public class LinkedListQueue<E> {
    private Node<E> front; //队头 删除元素
    private Node<E> rear;//队尾 添加元素

    class Node<E> {
        protected E data;
        protected Node<E> next;

        public Node(E data) {
            this.data = data;
        }
    }

    //判空
    public boolean isEmpty() {
        return front == null && rear == null;
    }

    public void push(E data) {
        Node<E> newNode = new Node<>(data);

        //rear 队尾 入队
        if (isEmpty()) {
            front = newNode;
            rear = front;
        } else {
            rear.next = newNode;
            rear = rear.next;
        }
    }

    public Node<E> pop() {
        if (isEmpty()) {
            return null;
        }

        //front 队头 出队
        Node<E> cur = front;
        front = front.next;

        return cur;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、基本概念和术语 数据(Data)  数据是信息的载体。它能够被计算机识别、存储和加工处理,是计算机程序加工的"原料"。  随着计算机应用领域的扩大,数据的范畴包括:  整数、实数、字符串、图像和声音等。 数据元素(Data Element)  数据元素是数据的基本单位。数据元素也称元素、结点、顶点、记录。  一个数据元素可以由若干个数据项(也可称为字段、域、属性)组成。数据项是具有独立含义的最小标识单位。 数据结构(Data Structure)  数据结构指的是数据之间的相互关系,即数据的组织形式。 1.数据结构一般包括以下三方面内容: ① 数据元素之间的逻辑关系,也称数据的逻辑结构(Logical Structure);  数据的逻辑结构是从逻辑关系上描述数据,与数据的存储无关,是独立于计算机的。数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。 ② 数据元素及其关系在计算机存储器内的表示,称为数据的存储结构(Storage Structure);  数据的存储结构是逻辑结构用计算机语言的实现(亦称为映象),它依赖于计算机语言。对机器语言而言,存储结构是具体的。一般,只在高级语言的层次上讨论存储结构。 ③ 数据的运算,即对数据施加的操作。   数据的运算定义在数据的逻辑结构上,每种逻辑结构都有一个运算的集合。最常用的检索、插入、删除、更新、排序等运算实际上只是在抽象的数据上所施加的一系列抽象的操作。  所谓抽象的操作,是指我们只知道这些操作是"做什么",而无须考虑"如何做"。只有确定了存储结构之后,才考虑如何具体实现这些运算。 为了增加对数据结构的感性认识,下面举例来说明有关数据结构的概念。 【例1.1】 学生成绩表,见下表。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值