什么是数据结构?
下面是维基百科的解释:
数据结构是计算机存储、组织数据的方式。数据结构意味着接口或封装:一个数据结构可被视为两个函数之间的接口,或者是由数据类型联合组成的存储内容的访问方法封装。
我们每天的编码中都会用到数据结构,下面是常见的数据结构:
- 数组(Array)
- 栈(Stack)
- 队列(Queue)
- 链表(Linked List)
- 散列表(Hash)
- 字典
- 树(Tree)
- 图(Graph)
- 堆(Heap)
堆(Heap)
JavaScript中的堆(Heap)是一块用于存储动态分配内存的区域。在这个堆里,我们可以存储复杂的数据结构,比如对象和数组。不同于栈(Stack),堆的大小不是固定的,而是可以根据需要动态扩展。
想象一下堆就像是一个大仓库,你可以往里面存放各种东西。每当你需要创建一个新的对象或数组时,JavaScript会在这个仓库里动态分配一块空间,然后把对象或数组放进去。这些存储在堆中的数据可以在程序的不同部分被引用和使用。
堆的灵活性使得我们能够处理复杂的数据,并能够动态地创建、修改和删除对象。就像购物时在超市的购物车中添加或移除物品一样,堆允许我们在程序中灵活地管理和使用数据。
堆的案例参考效果
当谈到JavaScript中的堆(Heap)时,通常指的是动态内存分配和存储对象的区域。虽然在JavaScript中不能直接访问和控制堆,但我们可以通过创建对象来演示堆的概念和动态分配特性。
下面是一个案例,它展示了使用HTML和JavaScript创建一个学生信息管理系统。在这个案例中,我们可以动态地添加和删除学生,并将它们的信息显示在页面上。
HTML\JS效果
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>学生管理系统</title><style>label {display: block;margin-bottom: 5px;}input[type="text"] {margin-bottom: 10px;}ul {list-style-type: none;padding: 0;}li {margin-bottom: 5px;}</style>
</head><body><h2>学生管理系统</h2><h3>添加学生</h3><label for="name">姓名:</label><input type="text" id="name"><label for="age">年龄:</label><input type="text" id="age"><button onclick="addStudent()">添加学生</button><h3>学生列表</h3><ul id="studentList"></ul><script>const students = [];function addStudent() {const nameInput = document.getElementById('name');const ageInput = document.getElementById('age');const name = nameInput.value;const age = ageInput.value;if (name && age) {const student = { name, age };students.push(student);nameInput.value = '';ageInput.value = '';displayStudents();}}function deleteStudent(index) {students.splice(index, 1);displayStudents();}function displayStudents() {const studentList = document.getElementById('studentList');studentList.innerHTML = '';students.forEach((student, index) => {const listItem = document.createElement('li');listItem.textContent = `${student.name} (年龄: ${student.age})`;const deleteButton = document.createElement('button');deleteButton.textContent = '删除';deleteButton.onclick = () => deleteStudent(index);listItem.appendChild(deleteButton);studentList.appendChild(listItem);});}</script>
</body></html>
案例代码思路和描述
这个案例是一个基本的学生信息管理系统,用户可以通过输入学生的姓名和年龄来添加学生,并以列表的形式显示学生的信息。每个学生条目都包含一个 "删除"
按钮,可以点击该按钮来删除对应的学生。
- 在HTML中,我们有一个用于输入学生姓名和年龄的表单,以及一个
"添加学生"
按钮来添加学生。还有一个用于显示学生列表的无序列表。 - 当用户点击
"添加学生"
按钮时,addStudent
函数会被调用。 addStudent
函数首先获取输入框中的姓名和年龄。- 如果姓名和年龄都存在,它会创建一个表示学生的对象,并将其添加到
students
数组中。 - 然后,它清空输入框中的姓名和年龄,并调用
displayStudents
函数来重新显示学生列表。 deleteStudent
函数用于删除学生。当用户点击某个学生后面的"删除"
按钮时,该学生将从students
数组中删除,并调用displayStudents
函数刷新列表。displayStudents
函数用于在页面上显示学生列表。它首先清空现有的列表项,然后遍历students
数组,并为每个学生创建一个列表项和对应的"删除"
按钮。最后,它将这些元素添加到无序列表中。
返回结果
你可以通过在文本框中输入学生的姓名和年龄,然后点击 "添加学生"
按钮来添加学生。添加的学生信息将显示在学生列表中,每个学生后面都有一个 "删除"
按钮。通过点击 "删除"
按钮,可以删除对应的学生。
这个案例演示了堆的概念,因为每次调用addStudent
函数时,JavaScript会在堆中动态分配内存以存储新的学生对象。这些对象在堆中被保存,即使方法执行结束,它们的引用仍然存在于students
数组中,直到被手动删除。
堆的常用场景
- 构建优先队列
- 支持堆排序
- 快速找出一个集合中的最小值(或者最大值)
堆内存与栈内存的区别
栈内存:
- 存放基本数据类型和对象变量的指针
- 自动分配固定大小的内存空间
- 由系统自动释放
堆内存:
- 存放引用类型(如object)等大小未知的对象类型数据
- 动态分配内存,大小不一,也不会自动释放
在JavaScript中,堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区。
持续学习总结记录中,回顾一下上面的内容:
JavaScript中的堆(Heap)是一块用于存储动态分配内存的区域。在这个堆里,我们可以存储复杂的数据结构,比如对象和数组。不同于栈(Stack),堆的大小不是固定的,而是可以根据需要动态扩展。