链表 - Part I
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
- 优点:可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。
- 缺点:链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
- 一般链表中只有一个表头
- 元素不是顺序存储的,不能随机访问
- 元素相互依赖,串联而成
构造一个链表:
首先创建两个模板类,一个用来创建链表节点对象,另一个用来创建链表:
1 template <typename Type> class Node { 2 public: 3 Type data; 4 Node<Type> *next; 5 6 Node(const Type &_data) { 7 data = _data; 8 next = nullptr; 9 } 10 }; 11 12 template <typename Type> class LinkedList { 13 private: 14 Node<Type> *head; 15 public: 16 LinkedList() { 17 head = nullptr; 18 } 19 ~LinkedList() { 20 Node<Type> *current_node = head; 21 while (current_node != nullptr) { 22 Node<Type> *delete_node = current_node; 23 current_node = current_node->next; 24 delete delete_node; 25 } 26 } 27 }
接下来给链表类添加如下的函数操作:
插入函数 insert(node, index),将node插入到链表中下标为index的位置:
实现方法:
1. 遍历到链表中要插入的位置的前一位。
2. 令待插入结点的 next 指针指向插入位置的当前结点。
3. 令插入位置之前的当前结点的 next 指针指向待插入结点。
1 bool insert(Node<Type> * node, int index) { 2 if (head == nullptr) { 3 if (index != 0) { 4 return false; 5 } 6 head = node; 7 return true; 8 } 9 if (index == 0) { 10 node -> next = head; 11 head = node; 12 return true; 13 } 14 Node<Type> * current_node = head; 15 int count = 0; 16 while (current_node -> next != nullptr && count < index - 1) { 17 current_node = current_node -> next; 18 count ++; 19 } 20 if (count == index - 1) { 21 node -> next = current_node -> next; 22 current_node -> next = node; 23 return true; 24 } 25 return false; 26 }
遍历函数output(),从头结点开始通过当前结点的指针找到下一节点直至表尾,并输出所有结点的值:
实现方法:
1. 定义一个用于遍历的变量,初始指向头结点。
2. 输出遍历变量所在结点的值,并更新遍历变量为当前结点的下一个结点。
3. 重复操作 2,直到遍历完所有结点。
1 void output() { 2 if (head == nullptr) { 3 return; 4 } 5 Node<Type> * current_node = head; 6 while (current_node != nullptr) { 7 cout << current_node -> data << " "; 8 current_node = current_node -> next; 9 } 10 cout << endl; 11 }
删除函数delete_node(index),删除链表中下标为index的元素:
实现方法:
1. 从表头遍历找到要删除的位置的前一位。
2. 令删除位置前一个结点的next指针指向待删除位置后一个结点。
3. 删除结点。
1 bool delete_node(int index) { 2 if (head == nullptr) { 3 return false; 4 } 5 Node<Type> * current_node = head; 6 int count = 0; 7 if (index == 0) { 8 head = head -> next; 9 delete current_node; 10 return true; 11 } 12 while (current_node -> next != nullptr && count < index - 1) { 13 current_node = current_node -> next; 14 count ++; 15 } 16 if (current_node -> next != nullptr && count == index - 1) { 17 Node<Type> * delete_node = current_node -> next; 18 current_node -> next = delete_node -> next; 19 delete delete_node; 20 return true; 21 } 22 return false; 23 }
翻转函数reverse(),翻转整个链表:
实现方法:
1. 定义一个用于遍历的指针,初始指向头结点后一个结点。
2. 让头结点的 next 指针置空。
3. 从当前遍历指针所指的结点开始遍历链表,将遍历到的结点 next 指针指向头结点。遍历过程中借助另外一个指针保存下一个遍历到的结点。
4. 重复步骤 3 直至表尾,此时新的链表就是原链表反转后的链表。
1 void reverse() { 2 if (head == nullptr) { 3 return; 4 } 5 Node<Type> * current_node, * next_node; 6 current_node = head -> next; 7 head -> next = nullptr; 8 while (current_node != nullptr) { 9 next_node = current_node -> next; 10 current_node -> next = head; 11 head = current_node; 12 current_node = next_node; 13 } 14 }
转载于:https://www.cnblogs.com/xudongwei/p/7493092.html
链表 - Part I相关推荐
- 伍六七带你学算法 入门篇-链表的中间节点
力扣-876链表的中间节点 难度-简单 给定一个带有头结点 head 的非空单链表,返回链表的中间结点. 如果有两个中间结点,则返回第二个中间结点. 示例 1: 输入:[1,2,3,4,5] 输出:此 ...
- Go 学习笔记(80)— Go 标准库 container/list(单链表、双链表)
列表是一种非连续存储的容器,由多个节点组成,节点通过一些变量记录彼此之间的关系.列表有多种实现方法,如单链表.双链表等. 在 Go 语言中,将列表使用 container/list 包来实现,内部 ...
- 数据结构(08)— 线性单链表基本操作
1. 线性单链表数据结构 // 假定每个结点的类型用 SNode 表示 typedef struct SNodeTag {int data; // 所存储的数据元素SNodeTag *next; // ...
- 数据结构(05)— 线性单链表实战
1. 设计思路 本项目的实质是完成对考生信息的建立.查找.插入.修改.删除等功能,可以首先定义项目的数据结构,然后将每个功能写成一个函数来完成对数据的操作,最后完成主函数以验证各个函数功能并得出运行结 ...
- 使用python建立简单的单链表
代码 import sysclass ListNode:def __init__(self, x):self.val = xself.next = None# 将列表转换成链表 def list_to ...
- LeetCode19. Remove Nth Node From End of List 删除链表中的倒数第n个位置的元素
前言 本文是LeetCode19. Remove Nth Node From End of List解法,这个题目需要删除链表中的倒数第n个位置的元素 代码 # -*- coding: utf-8 - ...
- 【数据结构】链表中的 指针,地址
数据结构中跳过集合,直接开始线性结构 线性结构中单链表的操作涉及到给一个变量赋值地址,所以涉及到了指针 通过指针里的地址很方便找到节点 但指针这里绕了我很长时间,不论学了多少遍也不敢说把指针学会了 地 ...
- LeetCode中等题之两两交换链表中的节点
题目 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点.你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换). 示例 1: 输入:head = [1,2,3,4] 输出:[ ...
- LeetCode简单题之合并两个链表
题目 给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个. 请你将 list1 中下标从 a 到 b 的全部节点都删除,并将list2 接在被删除节点的位置. 下图中蓝 ...
- LeetCode中等题之删除链表的中间节点
题目 给你一个链表的头节点 head .删除 链表的 中间节点 ,并返回修改后的链表的头节点 head . 长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点(下标从 0 开始),其中 ⌊ ...
最新文章
- python视频抽帧 后 前端javascript如何显示_使用OpenCV编写一个可以定时抽帧的脚本...
- Ext 整合 Jquery
- activiti 5.15.1 动态手动通过java编码方式,实现创建用户任务,动态指定个人,用户组,角色,指定监听的实现...
- laraver 用户认证auth、数据迁移和填充
- JAVA_OA管理系统(三)番外篇:Myeclipse导入Spring源码包
- u检验、t检验、F检验、X2检验 (转)
- Some cloud foundry deployment screenshot
- Halcon|读取3D相机点云数据
- matlab拟合四次函数表达式,用matlab编写程序求以幂函数作基函数的3次、4次多项式的最小二乘曲线拟合,画出数据散点图及拟合曲线图...
- Flex读取XML不刷新问题
- 2013年快要过去了,为新来的2104计划
- oracle11g调整表空间和临时表空间大小
- android html拦截广告,广告见鬼去!两招让安卓告别网页广告
- mysql创建数据库指定utf 8_MySQL创建数据库时指定编码utf8mb4和添加用户
- 游戏与计算机系统不兼容,电脑安装游戏时提示此文件版本与正在运行Windows不兼容的解决方法...
- JavaScript学习——JavaScript 循环
- 一个事务复制的bug--更新丢失 续
- 2018-2019-2 《网络对抗技术》Exp5 MSF基础应用 Week7-8 20165233
- 降雪致国道315线部分道路通行受阻公路交警部门昼夜坚守
- 【实战】python 小型商品销售统计系统