动态单向链表的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

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

C++中RAII资源获取即初始化

《C++中RAII资源获取即初始化》RAII通过构造/析构自动管理资源生命周期,确保安全释放,本文就来介绍一下C++中的RAII技术及其应用,具有一定的参考价值,感兴趣的可以了解一下... 目录一、核心原理与机制二、标准库中的RAII实现三、自定义RAII类设计原则四、常见应用场景1. 内存管理2. 文件操

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1