动态单向链表的C++实现

2024-08-22 10:18
文章标签 动态 c++ 实现 链表 单向

本文主要是介绍动态单向链表的C++实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.概念

链表是一种特殊的数组,它的每个元素称为节点,每个节点包括两个部分:

  • 数据域:存放数据,此部分与数组相同
  • 指针域:存放了下一个节点的地址(单向链表)、存放上一个和下一个节点的地址(双向链表)

其结构如下图所示


链表比数组多了指针域,因为链表结构是通过上一个节点的指针域去找下一个数据,比如有一个链表ABCD四个节点,其中A节点是链表的第一个节点,如果要访问D节点里边的数据。操作如下:

  1. 先通过A节点的指针域找到B节点
  2. 再通过B节点的指针域找到C节点
  3. 再通过C节点的指针域找到D节点
  4. 获取D节点数据域的数据

当遍历链表中的数据时,这种方法相比数组一般更加耗时,但是他的好处在于当插入和删除数据时非常方便,数组的插入和删除需要调整之后的每个数据,而链表则只需要调整结点的指针即可,如下图所示,删除同理


二.头指针和头结点

      头指针用来唯一确定单链表的身份,头指针指向链表的第一个结点,若第一个结点不存放数据,则为头结点。链表可以没有头结点,但必须有头指针,没有头指针的话链表也就不存在了。头结点的数据域可以不存放任何信息,也可以存放链表的长度等信息。

总结:

     头指针:

  • 在线性表的链式存储结构中,头指针是指链表指向第一个结点的指针,若链表有头结点,则头指针就是指向链表头结点的指针。
  • 头指针具有标识作用,常用头指针冠以链表的名字。
  • 无论链表是否为空,头指针均不为空。头指针是链表的必要元素。

头结点:

  • 头结点是为了操作的统一与方便而设立的,放在第一个元素结点之前,其数据域一般无意义(有些情况下也可存放链表的长度等等)。
  • 有了头结点后,对在第一个元素结点前插入结点和删除第一个结点,其操作与对其它结点的操作统一了。即操作任何位置时代码相同,更加方便。
  • 头结点不是链表所必需的。

三.实践

声明: LinkList.h

//
// Created by 开机烫手 on 2018/3/11.
//
#ifndef LINEARLIST_LINKLIST_H
#define LINEARLIST_LINKLIST_Hnamespace xq {typedef struct node {int data;struct node *next;} NODE;class LinkList {private:NODE* head;int len;LinkList(const LinkList&);public:LinkList();~LinkList();bool clearList();bool isEmpty();int length();void getElem(int, int *);int locateElem(int);bool insert(int, int);bool delete_(int,int*);void sort();void print();bool push_back(int);};}
#endif //LINEARLIST_LINKLIST_H

类实现:LinkList.cpp

//
// Created by 开机烫手 on 2018/3/11.
//
#include <iostream>
#include "LinkList.h"using namespace xq;
using namespace std;LinkList::LinkList() {head = new NODE;    // 创建头结点head->next = nullptr;len = 0;
}LinkList::~LinkList() {NODE *p = head->next;NODE *q;while (p) {q = p->next;delete p;p = q;}
}bool LinkList::clearList() {NODE *p = head->next;NODE *q;while (p) {q = p->next;delete p;p = q;}len = 0;head->next = nullptr;return true;
}bool LinkList::isEmpty() {return len == 0;
}int LinkList::length() {return len;
}void LinkList::getElem(int i, int *e) {if (i <= 0 || i > len || len == 0) {*e = -999;return;}int j = 1;NODE *p = head->next;while (j < i && p) {p = p->next;j++;}*e = p->data;
}int LinkList::locateElem(int e) {int i = 1;NODE *p = head->next;while (p) {if (p->data == e)return i;p = p->next;i++;}return -1;
}bool LinkList::insert(int i, int e) {if (i <= 0 || i-1 > len)return false;int j = 1;NODE *p = head;while (p && j < i) {p = p->next;j++;}NODE *s = new NODE;s->data = e;s->next = p->next;p->next = s;len++;return true;
}void LinkList::print() {if (len == 0) {cout << "list is empty!" << endl;return;}NODE *p = head->next;while (p) {cout << p->data << ' ';p = p->next;}cout << endl;
}bool LinkList::delete_(int i, int *e) {if (i <= 0 || i > len)return false;NODE *q = head;int j = 1;NODE *p = head->next;while (j < i) {q = p;p = p->next;j++;}*e = p->data;q->next = p->next;len--;delete p;return true;
}bool LinkList::push_back(int e) {NODE *p = head->next;while (p->next) {p = p->next;}NODE *s = new NODE;s->data = e;p->next = s;s->next = nullptr;len++;return true;
}void LinkList::sort() {if (len <= 1)return;int temp;NODE *p, *q;for (int i = 0; i < len - 1; i++) {p = head->next;q = head->next->next;for (int j = 0; j < len - 1 - i; j++) {if ((p->data) > (q->data)) {temp = p->data;p->data = q->data;q->data = temp;}p = p->next;q = q->next;}}
}

代码测试:main.cpp

#include <iostream>
#include "LinkList.h"using namespace std;
using namespace xq;int main() {cout << "----------List test programe!---------- " << endl;LinkList list1;cout << "is empty " << list1.isEmpty() << endl;list1.insert(1, 1);cout << "is empty " << list1.isEmpty() << endl;list1.clearList();cout << "is empty " << list1.isEmpty() << endl;list1.insert(1, 1);list1.insert(2, 2);list1.insert(3, 3);list1.insert(4, 5);list1.insert(5, 6);list1.print();list1.insert(4, 4);list1.print();int c;list1.delete_(5, &c);list1.print();int location = list1.locateElem(3);cout << "location is " << location << endl;int num2;list1.getElem(4, &num2);cout << "num2 = " << num2 << endl;list1.push_back(10);list1.push_back(5);list1.push_back(7);list1.push_back(2);list1.print();list1.sort();cout << "sort " ;list1.print();return 0;
}

程序输出为:

----------List test programe!----------
is empty 1
is empty 0
is empty 1
1 2 3 5 6
1 2 3 4 5 6
1 2 3 4 6
location is 3
num2 = 4
1 2 3 4 6 10 5 7 2
sort 1 2 2 3 4 5 6 7 10

这篇关于动态单向链表的C++实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1095990

相关文章

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库

linux下shell脚本启动jar包实现过程

《linux下shell脚本启动jar包实现过程》确保APP_NAME和LOG_FILE位于目录内,首次启动前需手动创建log文件夹,否则报错,此为个人经验,供参考,欢迎支持脚本之家... 目录linux下shell脚本启动jar包样例1样例2总结linux下shell脚本启动jar包样例1#!/bin

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Python实现PDF按页分割的技术指南

《Python实现PDF按页分割的技术指南》PDF文件处理是日常工作中的常见需求,特别是当我们需要将大型PDF文档拆分为多个部分时,下面我们就来看看如何使用Python创建一个灵活的PDF分割工具吧... 目录需求分析技术方案工具选择安装依赖完整代码实现使用说明基本用法示例命令输出示例技术亮点实际应用场景扩