数据结构Java实现02----线性表与顺序表

简介:

【正文】

本节内容:

  • 线性结构
  • 线性表抽象数据类型
  • 顺序表
  • 顺序表应用

 

一、线性结构

如果一个数据元素序列满足:

(1)除第一个和最后一个数据元素外,每个数据元素只有一个前驱数据元素和一个后继数据元素

(2)第一个数据元素没有前驱数据元素;

(3)最后一个数据元素没有后继数据元素。

则称这样的数据结构为线性结构。

 

二、线性表抽象数据类型:

1、线性表抽象数据类型的概念:

线性表抽象数据类型主要包括两个方面:既数据集合和该数据集合上的操作集合。

数据集合:

  可以表示为a0,a1,a2,...an-1,每个数据元素的数据类型可以是任意的类型。

操作集合包括如下:

1.求元素个数

2.插入

3.删除

4.查找

5.判断是否为空

2、设计线性表抽象数据类型的Java接口:

代码如下:

复制代码
//线性表接口
public interface List {
    //获得线性表长度
    public int size();
    //判断线性表是否为空
    public boolean isEmpty();
    //插入元素
    public void insert(int index,Object obj) throws Exception;
    //删除元素
    public void delete(int index) throws Exception;
    //获取指定位置的元素
    public Object get(int index) throws Exception;
}
复制代码

然后我们让子类去实现这个接口就行了。

 

三、顺序表:(在物理存储结构上连续,大小固定)

1、顺序表的概念:

计算机有两种基本的存储结构(物理存储结构):顺序结构、离散结构。使用顺序结构实现的线性表称为顺序表。如下图所示:

d3384f05-39d1-46d9-a580-bf4b531d740c

Java内存中,栈内存和堆内存占了很大一部分空间:栈内存的存储是顺序结构,堆内存的存储是离散结构。

 

2、设计顺序表类:

我们在上面第二段的List接口基础之上,设计一个顺序表:

(1)List.java:(线性表,和上面的第二段中代码一样)

复制代码
//线性表接口
public interface List {
    //获得线性表长度
    public int size();
    //判断线性表是否为空
    public boolean isEmpty();
    //插入元素
    public void insert(int index, Object obj) throws Exception;
    //删除元素
    public void delete(int index) throws Exception;
    //获取指定位置的元素
    public Object get(int index) throws Exception;
}
复制代码

(2)SequenceList.java:(核心代码)

复制代码
 1 public class SequenceList implements List {
 2 
 3     //默认的顺序表的最大长度
 4     final int defaultSize = 10;
 5     //最大长度
 6     int maxSize;
 7     //当前长度
 8     int size;
 9     //对象数组
10     Object[] listArray;
11 
12 
13     public SequenceList() {
14         init(defaultSize);
15     }
16 
17     public SequenceList(int size) {
18         init(size);
19     }
20 
21     //顺序表的初始化方法
22     private void init(int size) {
23         maxSize = size;
24         this.size = 0;
25         listArray = new Object[size];
26     }
27 
28     @Override
29     public void delete(int index) throws Exception {
30         // TODO Auto-generated method stub
31         if (isEmpty()) {
32             throw new Exception("顺序表为空,无法删除!");
33         }
34         if (index < 0 || index > size - 1) {
35             throw new Exception("参数错误!");
36         }
37         //移动元素
38         for (int j = index; j < size - 1; j++) {
39             listArray[j] = listArray[j + 1];
40         }
41         size--;
42     }
43 
44     @Override
45     public Object get(int index) throws Exception {
46         // TODO Auto-generated method stub
47         if (index < 0 || index >= size) {
48             throw new Exception("参数错误!");
49         }
50         return listArray[index];
51     }
52 
53     @Override
54     public void insert(int index, Object obj) throws Exception {
55         // TODO Auto-generated method stub
56         //如果当前线性表已满,那就不允许插入数据
57         if (size == maxSize) {
58             throw new Exception("顺序表已满,无法插入!");
59         }
60         //插入位置编号是否合法
61         if (index < 0 || index > size) {
62             throw new Exception("参数错误!");
63         }
64         //移动元素
65         for (int j = size - 1; j >= index; j--) {
66             listArray[j + 1] = listArray[j];
67         }
68 
69         listArray[index] = obj;  //不管当前线性表的size是否为零,这句话都能正常执行,即都能正常插入
70         size++;
71 
72     }
73 
74     @Override
75     public boolean isEmpty() {
76         // TODO Auto-generated method stub
77         return size == 0;
78     }
79 
80     @Override
81     public int size() {
82         // TODO Auto-generated method stub
83         return size;
84     }
85 }
复制代码

我们来看一下第54行的插入操作insert()方法:如果需要在index位置插入一个数据,那么index后面的元素就要整体往后移动一位。这里面需要特别注意的是:

插入操作:移动元素时,要从后往前操作,不能从前往后操作,不然元素会被覆盖的

删除元素:移动元素时,要从前往后操作。

(3)测试类:

复制代码
public class Test {

    public static void main(String[] args) {

        SequenceList list = new SequenceList(20);

        try {
            list.insert(0, 100);
            list.insert(0, 50);
            list.insert(1, 20);

            for (int i = 0; i < list.size; i++) {
                System.out.println("第" + i + "个数为" + list.get(i));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
复制代码

我们要注意插入的规则是什么,不然会觉得这个顺序表打印输出的顺序很奇怪。

运行效果:

0e1ffa91-ced8-4e2a-b247-9d19b51b2c19

  

3、顺序表效率分析:

  • 顺序表插入和删除一个元素的时间复杂度为O(n)。
  • 顺序表支持随机访问,顺序表读取一个元素的时间复杂度为O(1)。因为我们是可以通过下标直接访问的,所以时间复杂度是固定的,和问题规模无关。

4、顺序表的优缺点:

  • 顺序表的优点是:支持随机访问;空间利用率高(连续分配,不存在空间浪费)。
  • 顺序表的缺点是:大小固定(一开始就要固定顺序表的最大长度)插入和删除元素需要移动大量的数据。

 

5、顺序表的应用:

设计一个顺序表,可以保存100个学生的资料,保存以下三个学生的资料,并打印输出。

0393f396-1a75-4b69-927f-3e923f86d207

代码实现:

(1)List.java:

  和上面的代码保持不变

(2)SequenceList.java:

  和上面的代码保持不变

(3)Students.java:学生类

复制代码
//学生类
public class Students {

    private String id;// 学号
    private String name;// 姓名
    private String gender;// 性别
    private int age;// 年龄

    public Students() {

    }

    public Students(String sid, String name, String gender, int age) {
        this.id = sid;
        this.name = name;
        this.gender = gender;
        this.age = age;
    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "学号:" + this.getId() + " 姓名:" + this.getName() + " 性别:" + this.getGender() + " 年龄:" + this.getAge();
    }

}
复制代码

(4)Test.java:

复制代码
 1 public class Test {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         // TODO Auto-generated method stub
 8         SequenceList list = new SequenceList(100);
 9 
10         try {
11             list.insert(list.size, new Students("S0001", "张三", "男", 18)); //第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作。这一行里,size是等于0
12             list.insert(list.size, new Students("S0002", "李四", "男", 19));
13             list.insert(list.size, new Students("S0003", "王五", "女", 21));
14 
15             for (int i = 0; i < list.size; i++) {
16                 System.out.println(list.get(i));
17             }
18 
19         } catch (Exception ex) {
20             ex.printStackTrace();
21         }
22     }
23 
24 }
复制代码

注意第11行的注释:第一个参数list.size代表的是:我每次都是在顺序表的最后一个位置(当前线性表的长度的位置)进行插入操作;这样的话,遍历时才是按照张三、李四、王五的顺序进行输出的。

运行效果:

b0ccde4d-daf2-42c6-91e3-4f2f7a4e4b61

相关文章
|
1月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
50 7
|
1月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
49 5
|
1月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
50 5
|
2月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
64 5
|
3月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
73 6
|
3月前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
3月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
3月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!

热门文章

最新文章