• 浅谈数组和链表


    ​写在前面:

    数组和链表是数据结构中最基础的两种结构,其他的都是由这两者转化而来;
    因此,掌握这两种结构至关重要!下面,时光就带大家来学习一下数组和链表;

    思维导图:

    1,什么是线性表?

    线性表是具有相同类型的n(>=0)个数据元素的有限序列(a0,a1,a2,…,an),ai是表项,n是表长度;

    那么为什么要提到线性表呢?
    因为数组和链表都是线性表的结构,只不过它们的存储方式不一样;
    根据存储方式不同,可将线性表分为顺序表链式表
    线性表是数据结构中的逻辑结构。可以存储在数组上,也可以存储在链表上。
    一句话,用数组来存储的线性表就是顺序表

    2,数组和链表

    数组:在内存中,是一块连续的内存区域;
    链表:是由不连续的内存空间组成;

    3,数组和链表的区别

    数组优点: 随机访问性强,查找速度快(连续内存空间导致的);
    数组缺点: 插入和删除效率低 可能浪费内存 内存空间要求高,必须有足够的连续内存空间。数组大小固定,不能动态拓展

    链表的优点: 插入删除速度快 内存利用率高,不会浪费内存 大小没有固定,拓展很灵活。(每一个数据存储了下一个数据的地址,增删效率高)
    链表的缺点:不能随机查找,必须从第一个开始遍历,查找效率低

    4,数组和链表的代码实现

    说了这么多,让我们用代码来写一个数组和链表。
    数组:
    1,先写一个实体类DynamicArray;

    主要包括属性有数组容量,结点数据和数组长度;

     1package com.java.model;
     2
     3public class DynamicArray {
     4    //动态数组最大容量
     5    public final static int capacity = 100;
     6
     7    //顺序表的结点数据
     8    public int[] data;
     9    //顺序表的长度,用来标识数组中的元素个数
    10    public int size;
    11
    12    //构造函数
    13    public DynamicArray(int[] data, int size) {
    14        this.data = data;
    15        this.size = size;
    16    }
    17}
     

    2,再写数组方法类DynamicArrayDao;

    主要包括数组的各种操作方法,插入、查找等;

     1package com.java.dao;
      2
      3import com.java.model.DynamicArray;
      4import static com.java.model.DynamicArray.capacity;
      5
      6public class DynamicArrayDao {
      7
      8    //初始化数组
      9    public DynamicArray Init_Array(){
     10        //数组数据域初始化
     11        int[] data1=new int[capacity];
     12
     13        //DynamicArray初始化
     14        DynamicArray myArray=new DynamicArray(data1,0);
     15
     16        //数组赋值
     17        for(int i=0;i<capacity;i++){
     18            myArray.data[i]=0;
     19        }
     20        return myArray;
     21    }
     22
     23    //插入指定值
     24    public void PushBack_Array(DynamicArray array,int value){
     25        if(array==null){
     26            return;
     27        }
     28        //如果线性表容量小于或等于数组容量
     29        if(array.size==capacity){
     30            return;
     31        }
     32        //插入元素
     33        array.data[array.size]=value;
     34        array.size++;
     35    }
     36
     37    //根据位置删除
     38    public void RemoveByPos_Array(DynamicArray array,int pos){
     39        if (array == null){
     40            return;
     41        }
     42        //判断位置是否有效
     43        if(pos < 0 || pos >= array.size){
     44            return;
     45        }
     46        //删除元素
     47        for (int i = pos; i < array.size -1; i ++){
     48            array.data[i] = array.data[i + 1];
     49        }
     50        array.size--;
     51    }
     52
     53    //查找元素,返回该值第一次出现时对应的下标位置
     54    public int Find_Array(DynamicArray array,int value){
     55        if(array==null){
     56            return -1;
     57        }
     58        //找到该值第一次出现的位置,-1表示没有找到;
     59        int pos=-1;
     60        for(int i=0;i<array.size;i++){
     61            if(array.data[i]==value){
     62                pos=i;
     63                break;
     64            }
     65        }
     66        return pos;
     67    }
     68
     69    //根据位置查找到某个元素
     70    public int At_Array(DynamicArray array,int pos){
     71        if(array==null){
     72            return -1;
     73        }
     74        return array.data[pos];
     75    }
     76
     77    //根据值删除
     78    public void RemoveByValue_Array(DynamicArray array,int value){
     79        if(array==null){
     80            return;
     81        }
     82        //首先找到该值对应的数组下标
     83        int pos=Find_Array(array,value);
     84        //调用根据位置删除的方法
     85        RemoveByPos_Array(array,pos);
     86    }
     87
     88    //打印
     89    public void Print_Array(DynamicArray array){
     90        if(array==null){
     91            return;
     92        }
     93        for(int i=0;i<array.size;i++){
     94            System.out.print(array.data[i]+",");
     95        }
     96    }
     97
     98    //清空数组
     99    public void Clear_Array(DynamicArray array){
    100        if(array==null){
    101            return;
    102        }
    103        for(int i=0;i<array.size;i++){
    104            array.data[i]=0;
    105        }
    106        array.size=0;
    107    }
    108
    109    //获得动态数组当前元素个数
    110    public int Size_Array(DynamicArray array){
    111        if(array==null){
    112            return -1;
    113        }
    114        return array.size;
    115    }
    116}
     

    3,主函数Main;

    包括测试各种函数等;

     1package com.java.main;
     2
     3import com.java.dao.DynamicArrayDao;
     4import com.java.model.DynamicArray;
     5import static com.java.model.DynamicArray.capacity;
     6
     7public class DynamicArrayMain {
     8    public static void main(String[] args) {
     9        DynamicArrayDao dynamicArrayDao=new DynamicArrayDao();
    10        //初始化动态数组
    11        DynamicArray myArray=dynamicArrayDao.Init_Array();
    12        System.out.println("初始化动态数组:");
    13        //获取容量
    14        System.out.println("数组容量:"+capacity);
    15        System.out.println("数组实际大小:"+dynamicArrayDao.Size_Array(myArray));
    16        //插入元素
    17        for(int i=0;i<10;i++){
    18            dynamicArrayDao.PushBack_Array(myArray,i);
    19        }
    20        System.out.println();
    21
    22        System.out.println("插入元素之后:");
    23        //获取容量
    24        System.out.println("数组容量:"+capacity);
    25        System.out.println("数组实际大小:"+dynamicArrayDao.Size_Array(myArray));
    26        System.out.println();
    27
    28        //打印插入元素
    29        System.out.println("打印插入的元素:");
    30        dynamicArrayDao.Print_Array(myArray);
    31        System.out.println();
    32
    33        //根据元素位置删除元素
    34        dynamicArrayDao.RemoveByPos_Array(myArray,2);
    35        //根据元素值删除元素
    36        dynamicArrayDao.RemoveByValue_Array(myArray,7);
    37        System.out.println();
    38
    39        //打印删除后的数组
    40        System.out.println("打印删除后的元素:");
    41        dynamicArrayDao.Print_Array(myArray);
    42        System.out.println();
    43
    44        //查找元素为5的位置
    45        System.out.println();
    46        System.out.print("元素5的位置为: ");
    47        int pos=dynamicArrayDao.Find_Array(myArray,5);
    48        System.out.println(pos);
    49
    50        //查找位置为7的元素值
    51        System.out.println();
    52        System.out.print("位置为7的元素为: ");
    53        int value=dynamicArrayDao.At_Array(myArray,7);
    54        System.out.println(value);
    55
    56        //获取容量
    57        System.out.println();
    58        System.out.println("此时的数组容量:"+capacity);
    59        System.out.println("此时的数组实际大小:"+dynamicArrayDao.Size_Array(myArray));
    60        System.out.println();
    61    }
    62}
     

    运行效果:

    链表:
    1,先建立链表结点以及整个链表的实体类;

    这里有两个实体类:
    LinkNode是结点,包括结点的数据域和指针域;
    LinkList是整个链表,包括头结点以及链表元素个数;

     1package com.java.model;
     2
     3public class LinkNode {
     4    //链表结点的数据域
     5    public Object data;
     6    //链表结点的指针域
     7    public LinkNode next;
     8
     9    public LinkNode() {
    10        super();
    11        // TODO Auto-generated constructor stub
    12    }
    13
    14    //构造方法
    15    public LinkNode(Object data, LinkNode next) {
    16        super();
    17        this.data = data;
    18        this.next = next;
    19    }
    20
    21}
     
     1package com.java.model;
     2
     3public class LinkList {
     4    //链表的头结点
     5    public LinkNode head;
     6    //链表的元素个数
     7    public int size;
     8
     9    public LinkList() {
    10        super();
    11        // TODO Auto-generated constructor stub
    12    }
    13
    14    ///构造方法
    15    public LinkList(LinkNode head, int size) {
    16        super();
    17        this.head = head;
    18        this.size = size;
    19    }
    20
    21}
     

    2,再写链表方法类LinkListDao;

     1package com.java.dao;
     2
     3import com.java.model.LinkList;
     4import com.java.model.LinkNode;
     5
     6public class LinkListDao {
     7    //初始化链表
     8    public LinkList Init_LinkList(){
     9        //设置头结点的指针域和数据域
    10        LinkNode node=new LinkNode(0,null);
    11        LinkList list=new LinkList(node,0);
    12        return list;
    13    }
    14    //指定位置插入
    15    public void Insert_LinkList(LinkList list, int pos, Object data){
    16        //判断list是否有效
    17        if(list==null){
    18            return;
    19        }
    20        //判断data是否有效
    21        if (data==null){
    22            return;
    23        }
    24        //判断位置pos是否有效
    25        if (pos<0 || pos>list.size){
    26            //在链表的尾部插入
    27            pos = list.size;
    28        }
    29
    30        //第一步,创建新的结点,也就是待插入的结点
    31        LinkNode newNode=new LinkNode(data,null);
    32        //第二步,找到待插入结点前面一个结点pCurrent,并使其等于list的头结点
    33        LinkNode pCurrent=list.head;
    34        for(int i = 0 ; i < pos ; i++){
    35            pCurrent=pCurrent.next;
    36        }
    37        //第三步,新结点入链表,进行插入操作
    38        newNode.next=pCurrent.next;
    39        pCurrent.next=newNode;
    40        //第四步,链表的size要加1
    41        list.size++;
    42
    43    }
    44    //删除指定位置的值
    45    public void RemoveByPos_LinkList(LinkList list, int pos){
    46        if(list==null){
    47            return;
    48        }
    49        if(pos<0||pos>=list.size){
    50            return;
    51        }
    52        //第一步,找到待删除结点的前面一个结点pCurrent
    53        LinkNode pCurrent=list.head;
    54        for (int i = 0; i < pos; i++) {
    55            pCurrent=pCurrent.next;
    56        }
    57        //第二步,进行删除操作
    58        pCurrent.next=pCurrent.next.next;
    59        //第三步,链表的size要减1
    60        list.size--;
    61    }
    62    //获得链表的长度
    63    public int Size_LinkList(LinkList list){
    64        return list.size;
    65    }
    66    //查找指定元素的位置
    67    public void Find_LinkList(LinkList list, Object data){
    68        //注意这里要从头结点的下一个结点开始,因为头结点不存放数据信息
    69        LinkNode pCurrent=list.head.next;
    70        for (int i = 0; i < list.size; i++) {
    71            if(pCurrent.data==data){
    72                System.out.print(i+",");
    73            }
    74            pCurrent=pCurrent.next;
    75        }
    76    }
    77    //返回第一个结点元素的值
    78    public Object Front_LinkList(LinkList list){
    79        return list.head.next.data;
    80    }
    81    //打印链表结点
    82    public void Print_LinkList(LinkList list){
    83        if(list==null){
    84            return;
    85        }
    86        LinkNode pCurrent=list.head.next;
    87        for (int i = 0; i < list.size; i++) {
    88            System.out.print(pCurrent.data+",");
    89            pCurrent=pCurrent.next;
    90        }
    91    }
    92
    93}
     

    3,主函数Main;

    测试各种方法类;

    1package com.java.main;
     2
     3import com.java.dao.LinkListDao;
     4import com.java.model.LinkList;
     5
     6public class LinkListMain {
     7    public static void main(String[] args) {
     8        LinkListDao linkListDao=new LinkListDao();
     9        //创建链表
    10        LinkList list=linkListDao.Init_LinkList();
    11
    12        //数据插入链表
    13        linkListDao.Insert_LinkList(list, 0, "A");
    14        linkListDao.Insert_LinkList(list, 1, "B");
    15        linkListDao.Insert_LinkList(list, 2, "C");
    16        linkListDao.Insert_LinkList(list, 3, "D");
    17        linkListDao.Insert_LinkList(list, 4, "D");
    18
    19        //打印链表
    20        System.out.println("插入数据之后的链表为:");
    21        linkListDao.Print_LinkList(list);
    22        System.out.println();
    23
    24        //删除指定位置的值
    25        linkListDao.RemoveByPos_LinkList(list, 2);
    26
    27        //打印链表
    28        System.out.println("删除元素C之后的链表为:");
    29        linkListDao.Print_LinkList(list);
    30        System.out.println();
    31
    32        //获得链表长度
    33        System.out.println("链表长度为:");
    34        System.out.println(linkListDao.Size_LinkList(list));
    35
    36        //查找值为3的位置
    37        System.out.println("值为D的位置为:");
    38        linkListDao.Find_LinkList(list, "D");
    39        System.out.println();
    40
    41        //返回第一个结点元素的值
    42        System.out.println("第一个结点元素为:");
    43        System.out.println(linkListDao.Front_LinkList(list));
    44    }
    45}
     

    运行结果:

    文中代码格式是仿照MVC模式写的,建议大家也这样写,比较整齐我感觉。
    这次就分享到这里了,后续还有一系列的数据结构的文章哦,请大家期待!

                                   右下角点个再看吧!蟹蟹哦~

  • 相关阅读:
    操作系统——死锁相关
    Java 实现广度优先搜索和深度优先搜索
    Java 实现常见排序算法
    初次接触JQuery
    Firefox使用stylish自定义网页背景
    使用randoop自动化生成测试用例
    软件测试(五)——使用Selenium IDE进行自动化测试
    软件项目管理(二)——用jenkins持续集成、Maven、Github的使用
    云计算(一)——使用 Hadoop Mapreduce 进行数据处理
    软件测试(四)——图覆盖
  • 原文地址:https://www.cnblogs.com/huke123/p/12382176.html
Copyright © 2020-2023  润新知