【数据结构】线性表和顺序表

简介: 【数据结构】线性表和顺序表

框架


线性表


  • n 个具有相同特征的数据元素的有限序列
    常见的线性表:顺序表、链表、栈、队列…

  • 线性表在逻辑上是线性结构,也就是连续的一条直线
    但在物理结构上不一定是连续的,线性表在物理上存储时,通常以数组链式结构的形式进行存储

顺序表

  • 顺序表其实就是一个数组,是用一段物理地址连续的存储单元依次存储数据元素的线性结构
  • 其访问速度比较快,给定下标情况下,速度为 O (1)
  • 适用于经常进行下标查找或者更新的操作

顺序表实现逻辑

  1. 创建一个 IList 接口,用来放所有相关的方法
  2. 创建一个 MyArrayList 类,数组成员变量 int[ ] elem 用来放数据,整形成员变量 usedSize 用来记录数组里面的数据个数
  3. MyArrayList 类里面实现 IList 接口,并重写里面的方法

各种方法的实现

boolean isFull ()——判断数组是否放满

  • 直接返回 usedSize == elem.length 即可,相等为 true,不相等为 false
@Override
    public boolean isFull() {
        return usedSize == elem.length;
    }

void add (int data)——在数组末尾插入新元素

  1. 首先用 isFUll() 方法判断数组是否装满,若装满,就调用 ArrayscopyOf(elem, 2*elem.length) 方法对数组进行扩容
  2. 将第 usedSize 位的数组元素赋值为 data
  3. usedSize++;
@Override
    public void add(int data) {
        if(isFull()){
            //如果满了,就扩容为原来的两倍
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        elem[usedSize] = data;
        usedSize++;
    }

void add (int pos, int data)——在指定位置插入元素

  1. 首先判断传入的参数 pos 是否合法
  • 我们创建一个 checkPosOfAdd(int pos) 方法来进行判断,
  • (pos < 0 || pos >= usedSize) ,则抛出一个自定义异常 PosNotLegalException
  1. 再用 isFull() 方法判断数组是否装满,若装满,就调用 ArrayscopyOf(elem, 2*elem.length) 方法对数组进行扩容
  2. 移动元素,将后面的元素从后往前依次向后移一位 elem[usedSize] = elem[usedSize - 1];
  3. 插入元素,elem[pos] = data;
  4. usedSize++;
@Override
    public void add(int pos, int data) {
        //判断输入的 pos 是否合法
        try{
            checkAddPos(pos);
        }catch (PosNotLegalException e){
            e.printStackTrace();
        }
        //判断数组是否装满
        if(isFull()){
            elem = Arrays.copyOf(elem,elem.length*2);
        }
        //移动元素
        for (int i = usedSize - 1; i >= pos; i--) {
            elem[i + 1] = elem[i];
        }
        //插入元素
        elem[pos] = data;
        usedSize++;
    }
void checkPosOfAdd (int pos)——检查传入 add 方法中的 pos 是否合法
  • 若不合法则抛出一个自定义异常 PosNotLegalException
private void checkPosOfAdd(int pos) throws PosNotLegalException{  
    if(pos < 0 || pos > usedSize){  
        //自定义一个异常类:PosNotLegalException  
        throw new PosNotLegalException("pos位置不合法");    
    }
}

PosNotLegalException——传入参数不合法的自定义异常
  • 继承自运行时异常 RuntimeException
public class PosNotLegalException extends RuntimeException{  
    public PosNotLegalException(String msg) {  
        super(msg);  
    }
}

boolean contain (int toFind)——判断是否包含某个元素

  1. 遍历数组 usedSize 次
  2. elem[i] == toFind 时,return true;
  3. 找不到,return false;
public boolean contains(int toFind) {  
    //只需要寻找useSize次  
    for (int i = 0; i < usedSize; i++) {  
        if(elem[i]==toFind){  
            return true;  
        }    
    }   
    return false;  
}

int indexOf (int toFind)——查找某个对应元素的位置

  1. 遍历数组 usedSize
  2. elem[i] == toFind 时,return i;
  3. 找不到,return 0;
public int indexOf(int toFind) {  
    for (int i = 0; i < usedSize; i++) {  
        if(elem[i] == toFind)  
            return i;  
    }    return -1;  
}

int get (int pos)——获取 pos 位置的元素

  1. 判断传入的参数pos是否合法
  • 创建 checkPosOfGetAndSet(int pos) 方法来进行判断
  • (pos < 0 || pos > usedSize),则抛出自定义异常 PosNotLegalException
  1. 合法,return elem[pos];
public int get(int pos) {  
    try{  
        checkPosOfGet(pos);  
    }catch (PosNotLegalException e){  
        e.printStackTrace();  
    }    return elem[pos];  
}

void checkPosOfGetAndSet (int pos)——判断输入 get 和 set 方法的值是否合法
  • 若不合法则抛出一个自定义异常 PosNotLegalException
private void checkPosOfGet (int pos) throws PosNotLegalException{  
    if(pos < 0 || pos > usedSize){  
        throw new PosNotLegalException("pos位置不合法");  
    }
}

void set (int pos, int value)——将 pos 位置的元素设为 value

  1. 判断传入的参数pos是否合法
  • 调用 checkPosOfGetAndSet(int pos) 方法来进行判断
  • (pos < 0 || pos > usedSize),则抛出自定义异常 PosNotLegalException
  1. 赋值:elem[pos] == value;
public void set(int pos, int value) {  
    try {  
        checkPosOfGetAndSet(pos);  
    } catch (PosNotLegalException e) {  
        e.printStackTrace();  
    }    
    elem[pos] = value;  
}

void remove (int toRemove)——删除第一次出现的关键字

  1. 调用 indexOf() 方法,获取关键字的下标,并对下标进行判断,若 pos == -1,则输出“未找到
  2. 移动元素,将后面的元素从后往前依次向后移一位 elem[pos] = elem[pos + 1];
  3. usedSize--;
public void remove(int toRemove) {  
    int pos = indexOf(toRemove);  
  
    if (pos == -1) {  
        System.out.println("没有要找的关键字");  
    }    for (int i = pos; i < usedSize - 1; i++) {  
        elem[i] = elem[ i + 1];  
    }    this.usedSize--;  
}

void removeAll (toRemove)——删除所有出现的关键字

  1. 使用 for 循环多次调用 indexOf() 方法,若 pos != -1,则继续操作
  2. 移动元素,将后面的元素从后往前依次向后移一位 `elem[pos] = elem[pos + 1];
  3. usedSize--;
public void removeAll(int toRemove) {  
    for (int i = 0; i < usedSize; i++) {  
        int pos = indexOf(toRemove);  
        if (pos != -1) {  
            for (int j = pos; j < usedSize - 1; j++) {  
                elem[j] = elem[j + 1];  
            }            
            usedSize--;  
        }    
    }
}

void clear ()——清空顺序表

  • 因为是基本类型,直接 usedSize = 0 即可
  • 若是引用类型,则需将每一个位置的数据都置为 null (防止内存泄露)
public void clear() {  
    usedSize = 0;  
}


相关文章
|
9月前
|
存储 编译器 C语言
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
数据结构-顺序表详解(看这篇就足够了,哈哈哈)
124 2
|
6月前
|
存储 算法 测试技术
【C++数据结构——线性表】求集合的并、交和差运算(头歌实践教学平台习题)【合集】
本任务要求编写程序求两个集合的并集、交集和差集。主要内容包括: 1. **单链表表示集合**:使用单链表存储集合元素,确保元素唯一且无序。 2. **求并集**:遍历两个集合,将所有不同元素加入新链表。 3. **求交集**:遍历集合A,检查元素是否在集合B中存在,若存在则加入结果链表。 4. **求差集**:遍历集合A,检查元素是否不在集合B中,若满足条件则加入结果链表。 通过C++代码实现上述操作,并提供测试用例验证结果。测试输入为两个集合的元素,输出为有序集合A、B,以及它们的并集、交集和差集。 示例测试输入: ``` a c e f a b d e h i ``` 预期输出:
178 7
|
6月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】单链表的基本运算(头歌实践教学平台习题)【合集】
本内容介绍了单链表的基本运算任务,涵盖线性表的基本概念、初始化、销毁、判定是否为空表、求长度、输出、求元素值、按元素值查找、插入和删除数据元素等操作。通过C++代码示例详细解释了顺序表和链表的实现方法,并提供了测试说明、通 - **任务描述**:实现单链表的基本运算。 - **相关知识**:包括线性表的概念、初始化、销毁、判断空表、求长度、输出、求元素值、查找、插入和删除等操作。 - **测试说明**:平台会对你编写的代码进行测试,提供测试输入和预期输出。 - **通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了测试通过后的预期输出结果。 开始你的任务吧,祝你成功!
273 5
|
6月前
|
机器学习/深度学习 存储 C++
【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
本文档介绍了线性表的基本运算任务,涵盖顺序表和链表的初始化、销毁、判定是否为空、求长度、输出、查找元素、插入和删除元素等内容。通过C++代码示例详细展示了每一步骤的具体实现方法,并提供了测试说明和通关代码。 主要内容包括: - **任务描述**:实现顺序表的基本运算。 - **相关知识**:介绍线性表的基本概念及操作,如初始化、销毁、判定是否为空表等。 - **具体操作**:详述顺序表和链表的初始化、求长度、输出、查找、插入和删除元素的方法,并附有代码示例。 - **测试说明**:提供测试输入和预期输出,确保代码正确性。 - **通关代码**:给出完整的C++代码实现,帮助完成任务。 文档
162 5
|
7月前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
8月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
8月前
|
存储 C语言
【数据结构】顺序表(c语言实现)(附源码)
本文介绍了线性表和顺序表的基本概念及其实现。线性表是一种有限序列,常见的线性表有顺序表、链表、栈、队列等。顺序表是一种基于连续内存地址存储数据的数据结构,其底层逻辑是数组。文章详细讲解了静态顺序表和动态顺序表的区别,并重点介绍了动态顺序表的实现,包括初始化、销毁、打印、增删查改等操作。最后,文章总结了顺序表的时间复杂度和局限性,并预告了后续关于链表的内容。
204 3
|
8月前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之顺序表习题精讲【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找习题精讲等具体详解步骤以及举例说明
|
9月前
|
存储 Java
数据结构第二篇【关于java线性表(顺序表)的基本操作】
数据结构第二篇【关于java线性表(顺序表)的基本操作】
110 6
|
8月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之王道第2.3章节之线性表精题汇总二(5)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
IKU达人之数据结构与算法系列学习×单双链表精题详解、数据结构、C++、排序算法、java 、动态规划 你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!