• 数据结构基础


    数据结构:计算机存储、组织数据的方式,它用来反映一个数据的内部构成。

    数据:信息的载体,是能够被计算机识别、存储、计算(处理)的符号集合,是计算机处理对象的总称。
        数据含义在计算机语言中,十分广泛,除了通常使用的数字、字符串以外,任何能输入到并能被计算机处理的符号都可称为数据。
        例如,声音,图片等。

    数据元素:也称节点,组成数据的基本单位。可以由若干个数据项(也称字段、域、属性)组成。
        例如,短信箱中的一条短信。
        
    数据项:数据的最小单位,具有原子性,不可分割。
        例如,一个联系人中的姓名和手机号等。

    数据对象:具有相同特征的数据元素的集合,是数据的子集。
        例如,短信箱,通讯录等

    数据结构:逻辑结构 + 存储结构 + 数据运算
        1.逻辑结构:从逻辑关系上描述数据,与数据的存储(内存中的存储位置,存储方式等)无关,且独立于语言。
        2.存储结构:也称物理结构,指数据元素及其关系在计算机存储式如何表示,依赖语言。
        3.数据运算:通常定义在逻辑结构上,每种逻辑结构都有一个运算的集合,但运算的具体实现要在存储结构上进行。
            例如,数据对象的增删改查。
            
    逻辑结构按数据元素之间的相互关系分为线性结构和非线性结构
        1.线性结构
            有且只有一个开始节点和一个终端节点,并且所有节点最多只有一个直接前驱和一个直接后继节点。
        2.非线性结构
            一个节点可能有多个直接前驱和直接后继节点。常见的非线性结构,树和图。

    算法:为求解一个问题需要遵循的、被清晰地指定的简单指令的集合。通常以某一个数据集合作为输入,执行完一组特定的指令后,返回唯一的数据集合作为输出。
        特点:
            1.用待处理问题的信息作为输入数据。
            2.对一个既定的合法输入,多次执行同一算法,总是返回同一个结果(出随机算法除外)。
            3.算法中的指令都是可行的,即每个指令都可实现,并在有限的时间内完成。
            4.算法中的指令数量有限,即在有限的时间内,算法可以正确结束。
            5.算法执行完毕,能够输出正确的数据集合
        算法是一个指令集和,包括控制结构指令和操作指令。即,算法是循环、跳转、判断指令、和数据的操作指令的集合。
            
    算法分析:判断算法的执行效率。复杂度是判断算法优劣的标准,分为时间复杂度和空间复杂度。
        1.时间复杂度:算法执行的时间长短
        2.空间复杂度:算法在执行过程中所要占用的存储空间。它是额外消耗的存储空间,并不包括算法加载占用的存储空间。越复杂,算法越差。
        
    线性数据结构:线性表、栈、队列等
    非线性数据结构:树、图等
        
    ============线性表============
    线性表:
        1.数据元素之间是一对一关系
        2.以字符串、数组、栈、队列等形式使用

    特点:
        1.有且只有一个开始节点和一个终端节点
        2.内部节点均有且一个直接前驱和直接后继节点
        3.均匀性:不同线性表的数据元素可以多样,但是同一个线性表的数据元素必定是相同的类型
        4.有序性:数据元素在线性表中的位置只取决于序列,数据元素间的相对位置是线性的
        5.线性表具有增删改查操作。如果需要自定义线性表操作,那么一定要先定义线性表操作的接口,然后在接口中定义线性表的基本操作
        
    线性表的存储的数据在结构中的相对位置是随机的,即和数据的关键字不存在确定的关系,在结构中查找一条数据时,需要进行一系列和关键字做比较的动作。
        
    范例:

     1 public interface LinearList {
     2 //    判断线性表是否为空
     3     public boolean isEmpty();
     4 //    返回线性表的长度
     5     public int size();
     6 //    返回指定索引为index的对象
     7     public Object get(int index);
     8 //    用指定元素替换线性表中指定位置的元素
     9     public void set(int index,Object element);
    10 //    在线性表的指定位置插入指定元素
    11     public Boolean add(int index,Object element);
    12 //    在线性表的末尾插入指定元素
    13     public Boolean add(Object element);
    14 //    删除线性表中指定位置的元素
    15     public Object remove(int index);
    16 //    清空线性表
    17     public void clear();
    18 }


    存储方式:
        1.顺序存储:用一组连续的内存单元依次存放数据元素,数据元素在内存中的物理储存次序和在线性表中的逻辑次序相同。(数组)
            优点:存储密度大。因为存储单位的位置是连续的,几乎不浪费空间。
            缺点:插入,删除等不方便。
        2.链式存储:用一组地址分散的存储单元存储数据元素,逻辑上相邻的数据元素在物理位置不一定相邻。(单链表)
            特点:
                1.每个元素节点都有一个指针。(产生原因:存储单元地址是分散的,逻辑关系是连续的。它需要一个指针指向元素的后续节点的地址位置)
            分类:
                a.单链表:也称线性链表,有一个个节点链接而成。每个节点都有一个数据域(nodeValue)和指针域(next)。指针域指向下一个节点的内存存储地址。
                b.循环链表:在单链表的基础上,将表尾节点的指针域指向表头节点,整个链表形成环状结构。
                c.双链表:可同时向前和向后查找数据元素的单链表。每个节点都有一个数据域和previous和next指针域,分别指向直接前驱节点和直接后继节点。
    范例:
    1.顺序存储,实现线性表操作的接口LinearList - SequenceList

      1 public class SequenceList implements LinearList {
      2 
      3     // 声明对象数组
      4     private Object[] slist;
      5     // 声明线性表的长度
      6     private int size;
      7 
      8     /**
      9      * 调用带参构造方法
     10      */
     11     public SequenceList() {
     12         this(10);
     13     }
     14 
     15     public SequenceList(int length) {
     16         if (length <= 0) {
     17             this.slist = new Object[10];
     18         }
     19         this.slist = new Object[length];
     20         size = 0;
     21     }
     22 
     23     @Override
     24     public boolean isEmpty() {
     25         if (size == 0) {
     26             return true;
     27         } else {
     28             return false;
     29         }
     30         
     31     }
     32 
     33     @Override
     34     public int size() {
     35         return size;
     36     }
     37 
     38     @Override
     39     public Object get(int index) {
     40         checkIndex(index);
     41         return (Object)slist[index];
     42     }
     43 
     44     @Override
     45     public void set(int index, Object element) {
     46         checkIndex(index);
     47         slist[index] = element;
     48 
     49     }
     50 
     51     @Override
     52     public Boolean add(int index, Object element) {
     53         checkIndex(index);
     54         if (size == slist.length) {
     55             Object[] temp = slist;
     56             this.slist = new Object[temp.length * 2];
     57             for (int j = 0; j < temp.length; j++) {
     58                 slist[j] = temp[j];
     59             }
     60         }
     61         for (int i = size - 1; i >= index; i--) {
     62             slist[i + 1] = slist[i];
     63         }
     64         slist[index] = element;
     65         size++;
     66         return true;
     67     }
     68 
     69     @Override
     70     public Boolean add(Object element) {
     71         return add(size,element);
     72     }
     73 
     74     @Override
     75     public Object remove(int index) {
     76         checkIndex(index);
     77         Object old = (Object)slist[index];
     78         for (int i = index; i < size - 1; i++) {
     79             slist[i] = slist[i + 1];
     80         }
     81         slist[size--] = null;
     82         return old;
     83     }
     84 
     85     @Override
     86     public void clear() {
     87         if (size != 0) {
     88             for (int i = 0; i < size; i++) {
     89                 slist[i] = null;
     90             }
     91             size = 0;
     92         }
     93 
     94     }
     95     
     96     /**
     97      * @Description: 判断传入的索引值对于当前的线性表是否合法
     98      * @param index
     99      */
    100     public void checkIndex(int index) {
    101         if (index >= size || index < 0) {
    102             throw  new IndexOutOfBoundsException("index" + index + "size" + size);
    103         }
    104     }
    105 
    106 }


    2.单链表
    a.节点类 - Node

     1 public class Node {
     2     // 节点值
     3     private Object nodeValue;
     4     // 指针
     5     private Node next;
     6 
     7     public Node() {
     8         nodeValue = null;
     9         next = null;
    10     }
    11 
    12     /**
    13      * 初始化节点值
    14      * @param item
    15      */
    16     public Node(Object item) {
    17         nodeValue = item;
    18         next = null;
    19     }
    20 
    21     /**
    22      * 初始化节点值和指针
    23      * @param item
    24      * @param next
    25      */
    26     public Node(Object item,Node next) {
    27         nodeValue = item;
    28         this.next = next;
    29     }
    30 
    31     public Object getNodeValue() {
    32         return nodeValue;
    33     }
    34 
    35     public void setNodeValue(Object nodeValue) {
    36         this.nodeValue = nodeValue;
    37     }
    38 
    39     public Node getNext() {
    40         return next;
    41     }
    42 
    43     public void setNext(Node next) {
    44         this.next = next;
    45     }
    46 }


    b.SingleLinkedList

      1 public class SingleLinkedList implements LinearList {
      2 
      3     private Node head;
      4     
      5     /**
      6      * 初始化head为空
      7      */
      8     public SingleLinkedList(){
      9         head = null;
     10     }
     11     
     12     /**
     13      * 初始化head
     14      */
     15     public SingleLinkedList(Node head){
     16         this.head = head;
     17     }
     18     
     19     @Override
     20     public boolean isEmpty() {
     21         return head == null;
     22     }
     23 
     24     @Override
     25     public int size() {
     26         int size = 0;
     27         Node p = this.head;
     28         while (p != null) {
     29             size++;
     30             p = p.getNext();
     31         }
     32         return size;
     33     }
     34 
     35     @Override
     36     public Object get(int index) {
     37         checkIndex(index);
     38         Node p = this.head;
     39         for (int i = 0; i < index; i++) {
     40             p = p.getNext();
     41         }
     42         return (Object)p.getNodeValue();
     43     }
     44 
     45     @Override
     46     public void set(int index, Object element) {
     47         checkIndex(index);
     48         Node p = this.head;
     49         for (int i = 0; i < index; i++) {
     50             p = p.getNext();
     51         }
     52         p.setNodeValue(element);
     53 
     54     }
     55 
     56     @Override
     57     public Boolean add(int index, Object element) {
     58         if (index < 0) {
     59             throw new IndexOutOfBoundsException("index" + index);
     60         }
     61         if (head == null) {
     62             head = new Node(element);
     63         } else {
     64             Node p = this.head;
     65             if (index == 0) {
     66                 this.head = new Node(element,p);
     67             } else {
     68                 int i = 0;
     69                 while (p.getNext() != null && i < index - 1) {
     70                     i++;
     71                     p = p.getNext();
     72                 }
     73                 p.setNext(new Node(element,p.getNext()));
     74             }
     75         }
     76         return false;
     77     }
     78 
     79     @Override
     80     public Boolean add(Object element) {
     81         return add(Integer.MAX_VALUE, element);
     82     }
     83 
     84     @Override
     85     public Object remove(int index) {
     86         checkIndex(index);
     87         Object old = null;
     88         Node p = this.head;
     89         if (index == 0) {
     90             old = (Object)this.head.getNodeValue();
     91             head = p.getNext();
     92             p = null;
     93         } else {
     94             int i = 0;
     95             while (p.getNext() != null && i < index - 1) {
     96                 i++;
     97                 p = p.getNext();
     98             }
     99             Node temp = p.getNext();
    100             old = (Object)temp.getNodeValue();
    101             p.setNext(temp.getNext());
    102             temp = null;
    103         }
    104         return old;
    105     }
    106 
    107     @Override
    108     public void clear() {
    109         head = null;
    110 
    111     }
    112     
    113     public void checkIndex(int index) {
    114         if (index < 0 || index > this.size() - 1) {
    115             throw new IndexOutOfBoundsException("index" + index);
    116         }
    117     }
    118 
    119 }


    线性表的顺序查找
        除了增删查改等基本操作外,还有一些常见的操作,例如从线性表中获取数据的位置
    范例:有一个线性表,表中数据域存储A-G7个大写英文字母,查找“F”的位置。
    1.查找类

     1 /**
     2  * @Description: 查找类
     3  * @author Ivy
     4  */
     5 public class Search {
     6     public static int search_seq(LinearList ST,String key) {
     7         int i = 0;
     8         while (!ST.get(i).equals(key)) {
     9             i++;
    10         }
    11         return i;
    12     }
    13 }


    2.测试类

     1 public class Test {
     2     public static void main(String[] args) {
     3         LinearList ST = new SequenceList();
     4         String key = "F";
     5         ST.add("A");
     6         ST.add("B");
     7         ST.add("C");
     8         ST.add("D");
     9         ST.add("E");
    10         ST.add("F");
    11         ST.add("G");
    12         int i = Search.search_seq(ST, key);
    13         System.out.println("关键字F的位置:" + i);
    14     }
    15 }
  • 相关阅读:
    Python 数据类型:字典
    .Net开发工程师工具箱
    Javascript事件设计模式(七)
    LINQ学习之旅 (四)
    JavaScript实现抽象类与虚方法(六)
    Javascript中的反射机制(五)
    Javascript中类的实现机制(四)
    Javascript中的函数(三)
    Javascript面向对象基础(二)
    Web应用程序项目XXXX已配置为使用IIS。无法访问IIS 元数据库。您没有足够的特权访问计算机上的IIS
  • 原文地址:https://www.cnblogs.com/ivy-xu/p/5749485.html
Copyright © 2020-2023  润新知