Maoyl's blog Maoyl's blog
首页
  • 前端基础

    • HTML
    • CSS
    • CSS动画
    • JavaScript文章
    • stylus
  • 性能优化

    • 《性能优化》笔记
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《JavaScript设计模式》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架

    • Vue相关
    • React相关
  • 前端监控

    • 前端监控简介
  • 学习笔记

    • 《Vue》笔记
    • 《React》笔记
    • 小程序学习笔记
  • 后端基础

    • Nodejs
  • 学习笔记

    • 数据结构
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 网页性能
  • 学习笔记

    • 《Git》学习笔记
    • 《Vim》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

maoyln

日日行,不怕千万里
首页
  • 前端基础

    • HTML
    • CSS
    • CSS动画
    • JavaScript文章
    • stylus
  • 性能优化

    • 《性能优化》笔记
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《JavaScript设计模式》笔记
    • 《TypeScript 从零实现 axios》
    • TypeScript笔记
    • JS设计模式总结笔记
  • 前端框架

    • Vue相关
    • React相关
  • 前端监控

    • 前端监控简介
  • 学习笔记

    • 《Vue》笔记
    • 《React》笔记
    • 小程序学习笔记
  • 后端基础

    • Nodejs
  • 学习笔记

    • 数据结构
  • 技术文档
  • GitHub技巧
  • 博客搭建
  • 网页性能
  • 学习笔记

    • 《Git》学习笔记
    • 《Vim》学习笔记
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 第一讲 基本概念

  • 第二讲 线性结构

    • 1 线性表及其实现
      • 什么是线性表
      • 线性表的抽象数据类型描述
        • 线性表的实现
        • 总结
      • 线性表的链式存储实现
      • 多重链表
    • 2 堆栈
    • 3 队列
    • 4 应用实例:多项式加法运算
    • 5 小白专场:多项式乘法与加法运算- C实现
  • 第三讲 树(上)

  • 第四讲 树(中)

  • 第五讲 树(下)

  • 第六讲 图(上)

  • 《数据结构》学习笔记
  • 第二讲 线性结构
maoyln
2024-06-22
目录

1 线性表及其实现

# 什么是线性表

前言

1、同一个问题可以有不同的表示(存储)方法
2、有一类共性问题:有序线性序列的组织和管理
1
2

定义(仅供理解)

定义一:线性表(Linear List):由同类型数据元素构成有序序列的线性结构

定义二:线性表(Linear List):是一种基本的数据结构,用于存储一组有序的元素。线性表中的元素具有线性关系,即每个元素都有唯一的前驱和后继(除了第一个元素没有前驱和最后一个元素没有后继)。线性表可以通过顺序存储(数组)或链式存储(链表)来实现。


线性表初识

  • 表中元素个数称为线性表的长度;
  • 线性表没有元素时,称为空表;
  • 表起始位置称表头,表结束位置称表尾;

线性表的特点

  • 有序性:元素按线性顺序排列。
  • 唯一性:每个元素都有唯一的前驱和后继。
  • 动态性:元素的个数可以动态变化。

# 线性表的抽象数据类型描述

  • 类型名称:线性表(List)
  • 数据对象集:线性表是 **n (≥0)**个元素构成的有序序列 ( a1, a2, ...,an )
  • 操作集:线性表L ∈ List,整数i表示位置,元素X ∈ ElementType,线性表基本操作主要有:

线性表的方法

  1. 插入(Insert):在指定位置插入一个新元素;
  2. 删除(Delete):删除指定位置的元素;
  3. 查找(Find):查找指定元素的位置;
  4. 访问(Access):访问指定位置的元素;
  5. 更新(Update):更新指定位置的元素;
  6. 长度(Length):获取线性表的长度。

# 线性表的实现

线性表可以通过顺序存储结构(数组)和链式存储结构(链表)来实现。

顺序存储结构(数组)github (opens new window)

顺序存储结构使用一段连续的存储单元来存储线性表中的元素。数组是一种典型的顺序存储结构。

class ArrayList {
    constructor() {
        this.data = [];
    }

    // 获取元素个数
    size() {
        return this.data.length;
    }

    // 获取指定位置的元素
    get(index) {
        if (index < 0 || index >= this.size()) {
            throw new Error("Index out of bounds");
        }
        return this.data[index];
    }

    // 在指定位置插入元素
    insert(index, element) {
        if (index < 0 || index > this.size()) {
            throw new Error("Index out of bounds");
        }
        this.data.splice(index, 0, element);
    }

    // 删除指定位置的元素
    remove(index) {
        if (index < 0 || index >= this.size()) {
            throw new Error("Index out of bounds");
        }
        return this.data.splice(index, 1)[0];
    }

    // 输出所有元素
    print() {
        console.log(this.data.toString());
    }
}

// 使用示例
const list = new ArrayList();
list.insert(0, 'A'); // 插入元素 A 到位置 0
list.insert(1, 'B'); // 插入元素 B 到位置 1
list.insert(2, 'C'); // 插入元素 C 到位置 2
list.print(); // 输出:A,B,C

console.log(list.get(1)); // 获取位置 1 的元素,输出:B

list.remove(1); // 删除位置 1 的元素
list.print(); // 输出:A,C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

链表github (opens new window)

链表是一种使用节点和指针来实现的线性表,优点是插入和删除操作非常高效,缺点是访问任意位置的元素需要遍历链表。

class Node {
    constructor(element) {
        this.element = element;
        this.next = null;
    }
}

class LinkedList {
    constructor() {
        this.head = null;
        this.size = 0;
    }

    // 获取元素个数
    getSize() {
        return this.size;
    }

    // 在链表末尾添加元素
    append(element) {
        const newNode = new Node(element);
        if (this.head === null) {
            this.head = newNode;
        } else {
            let current = this.head;
            while (current.next !== null) {
                current = current.next;
            }
            current.next = newNode;
        }
        this.size++;
    }

    // 在指定位置插入元素
    insert(index, element) {
        if (index < 0 || index > this.size) {
            throw new Error("Index out of bounds");
        }
        const newNode = new Node(element);
        if (index === 0) {
            newNode.next = this.head;
            this.head = newNode;
        } else {
            let current = this.head;
            let previous = null;
            let currentIndex = 0;
            while (currentIndex < index) {
                previous = current;
                current = current.next;
                currentIndex++;
            }
            newNode.next = current;
            previous.next = newNode;
        }
        this.size++;
    }

    // 删除指定位置的元素
    remove(index) {
        if (index < 0 || index >= this.size) {
            throw new Error("Index out of bounds");
        }
        let current = this.head;
        if (index === 0) {
            this.head = current.next;
        } else {
            let previous = null;
            let currentIndex = 0;
            while (currentIndex < index) {
                previous = current;
                current = current.next;
                currentIndex++;
            }
            previous.next = current.next;
        }
        this.size--;
        return current.element;
    }

    // 输出所有元素
    print() {
        let current = this.head;
        let result = [];
        while (current !== null) {
            result.push(current.element);
            current = current.next;
        }
        console.log(result.toString());
    }
}

// 使用示例
const linkedList = new LinkedList();
linkedList.append('A'); // 添加元素 A
linkedList.append('B'); // 添加元素 B
linkedList.append('C'); // 添加元素 C
linkedList.print(); // 输出:A,B,C

linkedList.insert(1, 'D'); // 在位置 1 插入元素 D
linkedList.print(); // 输出:A,D,B,C

linkedList.remove(2); // 删除位置 2 的元素
linkedList.print(); // 输出:A,D,C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

# 总结

线性表是一种基本而重要的数据结构,广泛应用于各种算法和数据处理场景。顺序表和链表是两种主要的实现方式,各有优缺点,选择合适的实现方式取决于具体的应用场景和需求。

# 线性表的链式存储实现

不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。

  • 插入、删除不需要移动数据元素,只需要修改“链”。

# 多重链表

定义及属性 多重链表:链表中的节点可能同时隶属于多个链

  • 多重链表中结点的指针域会有多个,如前面例子包含了Next和SubList两个指针域;
  • 但包含两个指针域的链表并不一定是多重链表,比如在双向链表不是多重链表。

多重链表有广泛的用途: 基本上如树、图这样相对复杂的数据结构都可以采用多重链表方式实现存储。

编辑 (opens new window)
#数据结构
上次更新: 2025/04/18, 01:42:12
3 应用实例:最大子列和问题
2 堆栈

← 3 应用实例:最大子列和问题 2 堆栈→

最近更新
01
GSAP动画库——如何高效写动画
04-17
02
自适应方案PxToRem
09-10
03
性能优化-requestAnimationFrame
08-10
更多文章>
Theme by Vdoing | Copyright © 2019-2025 备案号:京ICP备19058102号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式