C++ 单向链表手动实现(课后作业版)

news2025/1/11 20:44:55

单向链表,并实现增删查改等功能

首先定义节点类,类成员包含当前节点的值和下一个节点的地址

/node definition
template <typename T>
class Node {
public:
    T value;
    Node<T>* next;

    Node() {}
    Node(const T& value) {
        this->value = value;
        next = nullptr;
    }
    Node(const T& value, const Node<T>& next) {
        this->value = value;
        this->next = next;
    }
};

然后是链表类的定义,主要包含了增删查改等功能

//linklist definition
template <typename T>
class LinkList {
public:
    Node<T>* headnode;

    LinkList();
    LinkList(const T* arr, int len);  //array initial
    LinkList(const LinkList<T>& link);
    ~LinkList();
    LinkList<T>& push_back(T n);
    LinkList<T>& push_front(T n);
    LinkList<T>& insert(int pos, int n, T* arr);
    LinkList<T>& pop_front();
    LinkList<T>& pop_back();
    LinkList<T>& remove(int pos, int num);
    T& operator[](int n);
    T& at(int n);
    LinkList<T>& replace(int pos, int n, T* arr);
    int getLen() {return len;}
    void clear() {this->~LinkList();}
    void display();
private:
    int len = 0;
    Node<T>* getNode(int n);

};

各个函数解释:

LinkList();      默认构造函数

LinkList(const T* arr, int len);      一般构造函数

LinkList(const LinkList<T>& link)           拷贝构造函数

~LinkList();     析构函数

LinkList<T>& push_back(T n);    在尾部添加一个元素

LinkList<T>& push_front(T n);     在头部添加一个元素

LinkList<T>& insert(int pos, int n, T* arr);   在pos处插入n个元素

LinkList<T>& pop_front();    删除第一个节点

LinkList<T>& pop_back();    删除最后一个节点

LinkList<T>& remove(int pos, int num);     删除pos开始的num个元素

T& operator[](int n);     重载[ ]运算符,返回第n个节点的值

T& at(int n);                 与[ ]一样,只不过会检查索引是否越界

LinkList<T>& replace(int pos, int n, T* arr);    替换n个节点

int getLen() {return len;}     返回长度,因为len是private

void clear() {this->~LinkList();}    清除链表

void display();    显示链表所有元素

Node<T>* getNode(int n);     返回第n个节点的指针,是private函数,在其他函数中经常用到

最后是各个成员函数的定义:

#include <iostream>
using namespace std;

//node definition
template <typename T>
class Node {
public:
    T value;
    Node<T>* next;

    Node() {}
    Node(const T& value) {
        this->value = value;
        next = nullptr;
    }
    Node(const T& value, const Node<T>& next) {
        this->value = value;
        this->next = next;
    }
};

//linklist definition
template <typename T>
class LinkList {
public:
    Node<T>* headnode;

    LinkList();
    LinkList(const T* arr, int len);  //array initial
    LinkList(const LinkList<T>& link);
    ~LinkList();
    LinkList<T>& push_back(T n);
    LinkList<T>& push_front(T n);
    LinkList<T>& insert(int pos, int n, T* arr);
    LinkList<T>& pop_front();
    LinkList<T>& pop_back();
    LinkList<T>& remove(int pos, int num);
    T& operator[](int n);
    T& at(int n);
    LinkList<T>& replace(int pos, int n, T* arr);
    int getLen() {return len;}
    void clear() {this->~LinkList();}
    void display();
private:
    int len = 0;
    Node<T>* getNode(int n);

};


//default constructor
template <typename T>
LinkList<T>::LinkList() {
    headnode = nullptr;
    len = 0;
}

//normal constructor
template <typename T>
LinkList<T>::LinkList(const T* arr, int len) {
    Node<T>* temp = nullptr;
    Node<T>* node = nullptr;
    if ( len < 0 ) {
        cout << "[error]: illegal length of LinkList" << endl;
        exit(0);
    }
    for ( int i = len-1; i >= 0; i-- ) {
        node = new Node<T>(i);
        node->value = *(arr+i);
        node->next = temp;
        temp = node;
        node = nullptr;
    }
    headnode = temp;
    this->len = len;
}

//copy constructor
template <typename T>
LinkList<T>::LinkList(const LinkList<T>& link) {
    this->len = link.getLen();
    this->headnode = link.headnode;
    link.headnode = nullptr;
}

//deconstructor
template <typename T>
LinkList<T>::~LinkList() {
    this->len = 0;
    Node<T>* temp = headnode;
    while ( headnode ) {
        temp = headnode;
        headnode = headnode->next;
        delete temp;
        temp = nullptr;
    }
}

//display all elements in Linklist<T>
template <typename T>
void LinkList<T>::display() {
    Node<T> *node = headnode;
    for ( int i = 0; i < len; i++ ) {
        cout << node->value << " ";
        node = node->next;
    }
    cout << endl;
}

//add one node at the last position
template <typename T>
LinkList<T>& LinkList<T>::push_back(T n) {
    Node<T> *node = this->getNode(len-1);

    if ( node->next == nullptr ) {
        Node<T> *temp = new Node<T>(n);
        node->next = temp;
        this->len++;
    }
    return *this;
}

//add one node at the first position
template <typename T>
LinkList<T>& LinkList<T>::push_front(T n) {
    Node<T>* node_new = new Node<T>(n);
    node_new->next = headnode;
    headnode = node_new;
    this->len++;
    return *this;
}

//insert elements to LinkList
template <typename T>
LinkList<T>& LinkList<T>::insert(int pos, int n, T* arr) {
    if ( pos > len-1 || len < 0 ) {
        cout << "[error]: illegal insert position, please check again" << endl;
        exit(0);
    }
    Node<T>* node_N = getNode(pos-1);  //前半部分
    Node<T>* temp = node_N->next;    //后半部分
    Node<T>* node_new = nullptr;     //新增加的
    for ( int i = 0; i < n; i++ ) {
        node_new = new Node<T> (arr[n-1-i]);
        node_new->next = temp;
        temp = node_new;
        node_new = nullptr;
    }
    node_N->next = temp;
    this->len += n;
    return *this;
}

//delete the first element
template <typename T>
LinkList<T>& LinkList<T>::pop_front() {
    if ( this->len == 0 ) {
        cout << "[error]: LinkList don't has any element" << endl;
        exit(0);
    }
    headnode = getNode(1);
    this->len--;
    return *this;
}

//delete the last element
template <typename T>
LinkList<T>& LinkList<T>::pop_back() {
    if ( this->len == 0 ) {
        cout << "[error]: LinkList don't has any element" << endl;
        exit(0);
    }
    Node<T>* temp = getNode(len-2);
    temp->next = nullptr;
    this->len--;
    return *this;
}

//get the last node pointer
template <typename T>
Node<T>* LinkList<T>::getNode(int n) {
    if ( n > len-1 || n < 0) {
        cout << "[error]: index out of range" <<endl;
    }
    Node<T> *node = headnode;
    for( int i = 0; i < n; i++ ) {
        node = node->next;
    }
    return node;
}

//remove n elements
template <typename T>
LinkList<T>& LinkList<T>::remove(int pos, int num) {
    if ( pos > len-1 || len < 0 ) {
        cout << "[error]: illegal remove position, please check again" << endl;
        exit(0);
    } else if ( pos + num > len) {
        cout << "[error]: remove index out of range" << endl;
        exit(0);
    }
    Node<T>* node_N = getNode(pos-1);
    node_N->next = getNode(pos+num);
    this->len -= num;
    return *this;
}

template <typename T>
T& LinkList<T>::operator[](int n) {
    if ( n > len-1 || n < 0 ) {
        cout << "[error]: index out of range" << endl;
        exit(0);
    }
    return this->getNode(n)->value;
}

template <typename T>
LinkList<T>& LinkList<T>::replace(int pos, int n, T* arr) {
    if ( pos > len-1 || len < 0 ) {
        cout << "[error]: illegal remove position, please check again" << endl;
        exit(0);
    } else if ( pos + n > len) {
        cout << "[error]: remove index out of range" << endl;
        exit(0);
    }
    Node<T>* temp = nullptr;
    if ( pos == 0 )
        temp = headnode;
    else
        temp = this->getNode(pos-1);
    for ( int i = 0; i < n; i++ ) {
        temp->value = arr[i];
        temp = temp->next;
    }
    return *this;
}

int main(){
    int arr[]{1,2,4,5,0};
    LinkList<int> link(arr, sizeof(arr)/sizeof(int));
    link.display();
    link.push_back(34);
    link.display();
    link.push_front(10);
    link.display();
    link.insert(3,4,arr);
    link.display();
    link.pop_front();
    link.display();
    link.pop_back();
    link.display();
    link.remove(2,3);
    link.display();
    cout << link[2] << endl;
    int a[] = {6,5,2};
    link.replace(2, sizeof(a)/sizeof(int), a);
    link.display();
    link.clear();
    cout << link.getLen() << endl;
    link.display();
}


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES6 入门教程 19 Generator 函数的语法 19.7 yield星号表达式

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程19 Generator 函数的语法19.7 yield* 表达式19 Generator 函数的语法 19.7 yield* 表达式 如果在 Generator 函数内部&…

windows域控批量创建账号方法

目录 一、收集信息 二、编写脚本 &#xff08;一&#xff09;新建aduser.ps1的powershell脚本 &#xff08;二&#xff09;New-Aduser命令详解 三、生产环境报错 &#xff08;一&#xff09;ConvertTo-SecureString &#xff08;二&#xff09;指定的账号已存在 &#xff…

debian11 安装后必备配置

debian11 安装后必备配置 运行环境&#xff1a;PVE v7.2-11 CT容器 系统版本&#xff1a;Debian-11-standard_11.3-1_amd64.tar.zst 启动信息 Debian GNU/Linux 11 debian tty1debian login: root Password: Linux debian 5.15.64-1-pve #1 SMP PVE 5.15.64-1 (Thu, 13 Oct …

【数据结构】堆的实现堆排序Top-K

文章目录一、堆的概念及结构二、堆实现&#xff08;1&#xff09;创建结构体&#xff08;2&#xff09;具体函数实现及解析1.0 交换函数1.1 堆的打印1.2 堆的初始化1.3 堆的销毁1.4 堆的插入1.5堆的向上调整算法1.6 堆的删除1.7堆的向下调整算法1.8 取堆顶的数据1.9 堆的数据个…

【力扣练习】找一个字符串中不含有重复字符的最长字串的长度

class Solution: def lengthOfLongestSubstring(self, s: str) -> int: # 哈希集合&#xff0c;记录每个字符是否出现过 occ set() n len(s) # 右指针&#xff0c;初始值为 -1&#xff0c;相当于我们在字符串的左边界的左侧&#xff…

【项目实战】Spring Boot项目抵御XSS攻击

本专栏将为大家总结项目实战相关的知识&#xff01; 点击即可关注本专栏&#xff0c;获取更多知识&#xff01; 文章目录前言一、什么是XSS攻击二、如何抵御XSS攻击三、实现抵御XSS攻击结语前言 作为Web网站来说&#xff0c;抵御XSS攻击是必须要做的事情&#xff0c;这是非常常…

C++基础知识

目录 C的基本使用 C数据的输入与输出 C使用命令行 具体案例 C生成随机数 关键字 标识符命名规则 数据类型 整形 实型&#xff08;浮点型&#xff09; 浮点型变量分为2种 表示小数的两种方式 案例演示 字符型 案例演示 字符串类型 两种风格 两种风格字符串之间…

【MyBatis】MyBtis入门程序

1. 目录结构 2. 数据库表的设计 /*Navicat Premium Data TransferSource Server : MysqlSource Server Type : MySQLSource Server Version : 50726Source Host : localhost:3306Source Schema : mybatisTarget Server Type : MySQLTarget Se…

python_循环

一、while循环的基础语法程序中的循环&#xff1a;while 条件&#xff1a;条件满足时&#xff0c;做的事情1条件满足时&#xff0c;做的事情2......即只要条件满足&#xff0c;会无限循环执行代码示例&#xff1a;# 简单示例&#xff1a;向Vivian表白100次i 0 while i < 10…

RabbitMQ系列【13】优先级队列

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言1. 设置优先级队列2. 消息设置优先级前言 RabbitMQ将消息写入队列中都是按顺序写的&#xff0c;消费时也是按顺序进行消费&#xff0c;队列中的消息是先进先出(FIFO).。 首先测试一下没有优…

多数银行人都会忽略5个影响系统性能的因素总结

性能测试往往在投产上线前开展&#xff0c;无法对整个系统变更进行全面的覆盖测试&#xff0c;因此性能测试需求提出十分关键。 性能测试需求交付过程中&#xff0c;需要对开发团队提出的测试需求进行审查&#xff0c;重点分析交付的测试需求是否充分覆盖了影响系统性能的因素…

【OpenCV-Python】教程:3-7 Canny边缘检测

OpenCV Python Canny 边缘检测 【目标】 Canny 边缘检测的概念cv2.Canny 【原理】 1. 去噪 由于边缘检测非常容易收到图像的噪声影响&#xff0c;第一步使用 5x5 高斯滤波去除图像中的噪声。 2. 寻找图像的亮度梯度 在平滑后&#xff08;去噪后&#xff09;的图像利用 S…

1.5 阻塞与非阻塞I/O

文章目录1、阻塞I/O2、非阻塞I/O3、异步I/O4、同步I/O5、epoll原理函数5.1、int epoll_create(int size)5.2、int epoll_ctl(int epfd,int op,int fd,struct epoll_event* event)5.3、int epoll_wait(int epfd,struct epoll_event* events,int maxevents,int timeout)5.4、内核…

【Linux 线程介绍】

Linux 线程线程一定越多越好吗&#xff1f;线程的实现方式&#xff1a;API:pthread_exit函数演示获取线程的返回值多线程的不安全性查看进程中的线程数进程&#xff1a;一个正在运行的程序 &#xff0c;资源分配的基本单位 线程&#xff1a;进程内部的一条执行序列&#xff08;…

接口自动化测试

接口自动化测试1.基础知识1.接口测试原理2.接口测试点及用例设计方法3.接口测试返回值的处理4.接口测试要点5.常见HTTP状态码6.HTTP基础知识7.接口自动化测试工具2.抓包工具1.chrom抓包2.Fiddle抓包&#xff08;PC端&#xff0c;手机端&#xff09;1.原理2.下载安装3. 认识界面…

HIbernate多表学习

一&#xff0c;表与表之间关系&#xff1a; 1.一对多&#xff1a;多的表用一个外键存一的表的主键id。 2.多对多&#xff1a;新建第三张表&#xff0c;两个外键分别存两个多的表的主键id。 3.一对一 二&#xff0c;Hibernate一对多练习&#xff1a; 一对多映射配置&#…

国际通用回收标准-GRS、RCS的答疑

【国际通用回收标准-GRS、RCS的答疑】 GRS & RCS 国际通用回收标准 GRS和 RCS是目前现行国际公认的回收材料标准。许多国际知名品牌如 ADDIDAS、3M、PUMA、H&M、NIKE等都是此标准的会员。GRS与 RCS最早开始于纺织产业&#xff0c;用以证明其产品或原料含有一定的回收材…

yolov5剪枝实战4: 正常训练和稀疏化训练

1. 准备自己的数据集 1.1 下载项目文件 准备好备注的数据集进行训练,我这里给出了标注好的足球的数据集。从百度网盘下载到项目目录下并解压,网盘地址见文末 VOCdevkit_ball.ziptestfiles.zipprepare_data.py1.2 解压建立或自行建立数据集 使用PASCAL VOC数据集的目录结构,…

怎么批量把图片转文字?教你几招轻松完成

工作中我们经常要与图片、文字打交道&#xff0c;特别是做资料收集的小伙伴&#xff0c;当收到图片资料的时候&#xff0c;就需要将其输出为文字进行保存&#xff0c;如果是单张的时候我们还可以使用手机或者微信直接拍照识别转&#xff0c;但是图片不止一张的时候&#xff0c;…

nvcc编译器之GPU代码编译(chapter 5)

目录 5. GPU编译 5.1 GPU多代架构 5.2 GPU特性列表 5.3 应用兼容性 5.4 虚拟架构 5.5 虚拟架构特性列表 5.6 兼容性补全机制 5.7 nvcc示例 5. GPU编译 本章描述了由nvcc与CUDA驱动协同维护的GPU编译模型。本文介绍了一些技术部分&#xff0c;并在最后给出了具体的示例…