基础数据结构

别说谁变了你拦得住时间么 提交于 2019-12-21 23:45:06

java - 数据结构 - 基础数据结构

整理所学,期待批评指教

基础概念

  • 数据

    • 描述客观事物的数值、字符以及能输入到计算机中且能被处理的各种符号集合
  • 数据元素

    • 组成数据的基本单位,数据集合的个体,计算机中通常作为一个整体进行考虑
  • 数据对象

    • 性质相同的数据元素的集合,数据的一个子集
  • 数据结构

    • 相互之间存在一种或多种特定关系的数据元素的集合

    • 是一个二元组:

      D —>数据有限集

      R —>D上关系的有限集

      • Data_Stracture = (D, R)
  • 数据类型

    • 性质相同的值集合以及定义在这个值集合上的一组操作的总称。
  • 数据抽象与抽象数据类型

    • 抽象数据类型(Abstract Data Type)ADT
      • 含义:数据模型及定义在数据模型上的操作
      • 特征:使用与实现分离,实现信息封装及隐蔽
    • 抽象数据类型实现
      • 1.面向过程设计
        • 逻辑架构—>选定存储结构,操作要求—>设计子程序或子函数
      • 2.“包”,“模型”设计方法
        • 可单独编译,同时提供了外部使用的方便
      • 3.面向对象程序设计(Object Oriented Programming,OOP)
        • 着眼于应用问题涉及的对象,包括对象,对象属性和要求

1.数据结构内容

1.1 数据的逻辑结构

数据逻辑间关系的描述

  • 依据数据间不同关系划分
    • 集合结构:结构中数据元素除同属于一个集合外无任何关系
    • 线性结构:结构中数据元素存在着一对一的线性关系
    • 树型结构:结构中的数据元素之间存在着一对多的层次关系
    • 图状结构:结构中的数据元素之间存在着多对多的任意关系
  • 依据数据元素间关系的不同特性
    • 线性结构:
      • 线性表,栈,队列,字符串,数组和广义表
    • 非线性结构:
      • 树和图

1.2 数据的存储结构

  • 数据元素在计算机中的表示方式
    • 顺序映像—>顺序存储
    • 非顺序映像—>链式存储

1.3 数据的运算

Niklaus Wirth提出的著名公式:数据结构 + 算法 = 程序

  • 算法特征
    • 有穷性:任意一组合法输入值,又穷步骤后一定能结束
    • 确定性:每一步是确切定义的,算法的执行者或者阅者都能明确其含义以及如何执行,并且在任何条件下,算法只有一条执行路径
    • 可行性:算法中所有操作必须足够基本,都可以通过已实现的基本操作运算有限次实现
    • 有输入:算法应该有0个或多个输入
    • 有输出:算法应该有1个或多个输出
  • 算法评定标准
    • 正确性
    • 可读性
    • 健壮性
    • 高效率与低存储量需求

2.线性表

2.1 线性表基本概念

  • 特点:
    • 同一性
    • 有穷性
    • 有序性

2.2 线性表的实现

存储方式:链式存储,顺序存储

2.2.1 基本概念

  • 逻辑上相邻的物理存储上也是相邻的

  • 计算函数:

    • 第一个元素存放地址LOC(a1),每个元素占用d个字节

      LOC(ai) = LOC(a1) + d x (i-1) 1<= i <= n

  • 优势存取随机

2.2.2 实现

  • 规定其接口

    package algorithm.base.linearList;
    
    /**
     * @ClassNameMyList
     * @Description
     * @Author ANGLE0
     * @Date 2019/12/21 14:44
     * @Version V1.0
     **/
    public interface MyList {
        void clear();
    
        boolean isEmpty();
    
        int length();
    
        Object get(int i) throws Exception;
    
        void insert(int i, Object x) throws Exception;
    
        void remove(int i) throws Exception;
    
        int indexOf(Object x);
    
        void display();
    }
    

2.2.2.1顺序存储实现

package algorithm.base.linearList;

/**
 * @ClassNameArrayList
 * @Description
 * @Author ANGLE0
 * @Date 2019/12/21 13:03
 * @Version V1.0
 **/
public class MyArrayList implements MyList{

    private Object[] elements;

    private int length;

    public MyArrayList(int length) {
        this.elements = new Object[length];
        this.length = 0;
    }

    /**
     * @Desc:  [清空顺序表]
     * @param :  void
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 14:51
     * @version : v1.0
     */
    public void clear() {
        this.length = 0;
    }

    /**
     * @Desc:  [是否为空]
     * @param :  void
     * @return : boolean
     * @author :  ANGLE0
     * @createTime :  2019/12/21 14:51
     * @version : v1.0
     */
    public boolean isEmpty() {
        return this.length == 0;
    }

    /**
     * @Desc:  [返回当前顺序表的长度]
     * @param :  void
     * @return : int
     * @author :  ANGLE0
     * @createTime :  2019/12/21 14:50
     * @version : v1.0
     */
    public int length() {
        return this.length;
    }

    /**
     * @Desc:  [返回指定位置数据值]
     * @param :  int
     * @return : Object
     * @author :  ANGLE0
     * @createTime :  2019/12/21 14:52
     * @version : v1.0
     */
    public Object get(int i) throws Exception {
        if (i < 0 && i > this.length)
            throw new NullPointerException("顺序表中不存在"+i+"位置");
        return elements[i];
    }

    /**
     * @Desc:  [在指定位置插入值,前置插入]
     *          eg:[ 1, 2, 3, 4, 5] ---> insert(2, 0) ---> [1, 0, 2, 3, 4, 5]
     * @param :  int , Object
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 14:59
     * @version : v1.0
     */
    public void insert(int i, Object in) throws Exception {
        //边界判定
        if (i == elements.length)
            throw new Exception("当前表已满,插入失败");
        if (i < 0 || i > elements.length)
            throw new NullPointerException("插入"+i+"位置不合适,数据"+in.toString()+"插入失败");
        //为即将插入的值调整空间
        for (int j = this.length; j > i; j--){
            elements[j] = elements[j-1];
        }
        //赋值修改顺序表元素长度记录
        elements[i] = in;
        this.length++;
    }

    /**
     * @Desc:  [移除当前位置所指向的元素]
     * @param :  int
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 15:17
     * @version : v1.0
     */
    public void remove(int i) throws Exception {
        //边界判定
        if (this.length == 0)
            throw new NullPointerException("顺序表已空");
        if (i > this.length || i < 0)
            throw new NullPointerException("要移除的"+i+"位置不存在");
        //元素左移,覆盖原有值,实现删除
        for (int j = i; j < this.length-1; j++) {
            elements[j] = elements[j+1];
        }
        //修改顺序表长度记录
        this.length--;
    }

    /**
     * @Desc:  [查找指定值在顺序表中的位置]
     * @param :  Object
     * @return : int
     * @author :  ANGLE0
     * @createTime :  2019/12/21 15:23
     * @version : v1.0
     */
    public int indexOf(Object x) {
        int index = 0;//记录当前扫描位置
        while (index < this.length && !elements[index].equals(x)){
            index++;
        }
        return index < this.length ? index : -1;
    }

    /**
     * @Desc:  [打印顺序表值]
     * @param :  void
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 15:23
     * @version : v1.0
     */
    public void display() {
        System.out.print("[");
        for (int i = 0; i < this.length-1; i++) {
            System.out.print(" "+ elements[i] + ",");
        }
        System.out.print(" "+ elements[this.length-1] + "]\n");
    }
}

测试

public static void main(String[] args) throws Exception {
    MyArrayList L = new MyArrayList(10);
    for (int i = 0; i < 8; i++)
        L.insert(i, i);
    System.out.println("删除索引为1的元素");
    L.remove(1);
    L.display();
    System.out.println("索引为3处插入元素");
    L.insert(3, 5);
    L.display();
    System.out.println("获取索引为1的元素值");
    System.out.println(L.get(1));
}
/* 测试结果为*/
删除索引为1的元素
[ 0, 2, 3, 4, 5, 6, 7]
索引为3处插入元素
[ 0, 2, 3, 5, 4, 5, 6, 7]
获取索引为1的元素值
2

2.2.2.2 链式存储实现

package algorithm.base.linearList.link;

import algorithm.base.linearList.MyList;

import javax.management.loading.MLet;

/**
 * @ClassNameMyLinkedList
 * @Description
 * @Author ANGLE0
 * @Date 2019/12/21 17:14
 * @Version V1.0
 **/
public class MyLinkedList<E> implements MyList {

    private E data;
    private MyLinkedList next;

    public MyLinkedList() {
    }

    /**
     * @Desc:  [初始化链表]
     * @param :  MyLinkedList
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 17:22
     * @version : v1.0
     */
    public MyLinkedList(Object x) {
        this.data = (E)x;
        this.next = null;
    }

    /**
     * @Desc:  [清空链表]
     * @param :  void
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 17:22
     * @version : v1.0
     */
    public void clear() {
        this.next = null;
    }

    /**
     * @Desc:  [链表是否为空]
     * @param :  void
     * @return : boolean
     * @author :  ANGLE0
     * @createTime :  2019/12/21 17:23
     * @version : v1.0
     */
    public boolean isEmpty() {
        return this.data == null && this.next == null;
    }

    /**
     * @Desc:  [链表长度]
     * @param :  void
     * @return : int
     * @author :  ANGLE0
     * @createTime :  2019/12/21 17:23
     * @version : v1.0
     */
    public int length() {
        int count = 0;
        MyLinkedList linkedList = this;
        if (linkedList != null){
            count++;
            linkedList = linkedList.next;
        }
        return count;
    }

    /**
     * @Desc:  [获取索引为i的值]
     * @param : void
     * @return : Object
     * @author :  ANGLE0
     * @createTime :  2019/12/21 17:26
     * @version : v1.0
     */
    public E get(int i) throws Exception {
        int count = 0;
        MyLinkedList linkedList = this;
        while (count < i){
            linkedList = linkedList.next;
        }
        return (E)linkedList.data;
    }

    /**
     * @Desc:  [插入节点,前置插入]
     * @param :  int, Object
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 18:35
     * @version : v1.0
     */
    public void insert(int i, Object x) throws Exception {
        MyLinkedList myLinkedList = this.NodePreI(i);
        //创建新元素并嵌入链表中
        MyLinkedList newNode = new MyLinkedList(x);
        newNode.next = myLinkedList.next;
        myLinkedList.next = newNode;
    }

    /**
     * @Desc:  [移除第i个节点]
     * @param :  int
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 18:39
     * @version : v1.0
     */
    public void remove(int i) throws Exception {
        MyLinkedList myLinkedList = NodePreI(i);
        myLinkedList.next = myLinkedList.next.next;
    }

    /**
     * @Desc:  [返回第i-1个节点]
     * @param :  int
     * @return : MyLinkedList
     * @author :  ANGLE0
     * @createTime :  2019/12/21 18:54
     * @version : v1.0
     */
    private MyLinkedList NodePreI(int i) {
        MyLinkedList myLinkedList = this;
        if (this == null)
            throw new NullPointerException("链表为空,索引"+i+"位置无效");
        if (i < 0){
            throw new NullPointerException("索引位置越界,索引"+i+"无效");
        }
        //遍历到第i个节点前一个节点
        for (int j = 0; j < i-1; j++) {
            myLinkedList = myLinkedList.next;
        }
        return myLinkedList;
    }

    /**
     * @Desc:  [查找出第一个值为x的索引位置]
     * @param :  Object
     * @return : int -1代表查询无结果
     * @author :  ANGLE0
     * @createTime :  2019/12/21 18:40
     * @version : v1.0
     */
    public int indexOf(Object x) {
        MyLinkedList myLinkedList = this;
        if (this == null)
            throw new NullPointerException("链表为空,查找失败");
        MyLinkedList myLinkedList1 = this;
        int count = 0;
        while (myLinkedList1.next != null && myLinkedList1.data.equals(x)) {
            myLinkedList1 = myLinkedList1.next;
            count++;
        }
        return count > this.length() ? -1 : count;
    }

    /**
     * @Desc:  [打印当前链表的所有值]
     * @param :  void
     * @return : void
     * @author :  ANGLE0
     * @createTime :  2019/12/21 18:44
     * @version : v1.0
     */
    public void display() {
        MyLinkedList myLinkedList = this;
        while (myLinkedList.next != null){
            System.out.print(myLinkedList.data + "-->");
            myLinkedList = myLinkedList.next;
        }
        System.out.print("\b\b\b   \n");
    }
}

测试

public static void main(String[] args) throws Exception {
    MyLinkedList myLinkedList = new MyLinkedList(0);
    for (int i = 0; i < 10; i++) {
        myLinkedList.insert(i, i);
    }
    System.out.println("建立链表如下:");
    myLinkedList.display();
    System.out.println("索引为1处插入数值9");
    myLinkedList.insert(1, 9);
    myLinkedList.display();
    System.out.println("移除索引为3的节点");
    myLinkedList.remove(3);
    myLinkedList.display();
    System.out.println("清除链表");
    myLinkedList.clear();
    myLinkedList.display();
}
/* 测试结果 */
建立链表如下:
0-->1-->2-->3-->4-->5-->6-->7-->8-->9   
索引为1处插入数值9
0-->9-->1-->2-->3-->4-->5-->6-->7-->8-->9   
移除索引为3的节点
0-->9-->1-->3-->4-->5-->6-->7-->8-->9   
清除链表
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!