链表的结构
1.1单向链表
(单)链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域,一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向 null(空指针的意思)。链接的入口节点也就是 head(头结点)
c++ 代码实现
这里我用的编辑器是Cloin
2.1 项目结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/bc6d3d756607432bab1ba7c407424699.png)
2.2 配置文件:CMakeLists.txt
cmake_minimum_required(VERSION 3.26)
project(LinkedListEnterprise)
# 设置 C++ 标准为 C++17
set(CMAKE_CXX_STANDARD 17)
# 设置输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# 添加链表库的源文件
set(LINKEDLIST_SOURCES
src/linkedList/Node.cpp
src/linkedList/LinkedList.cpp
# ... 添加其他链表相关的源文件
)
# 添加其他模块或库的源文件
#set(OTHER_MODULE_SOURCES
# src/other_module/OtherModule.cpp
# # ... 添加其他模块相关的源文件
#)
# 添加可执行文件
add_executable(main src/main.cpp ${LINKEDLIST_SOURCES})
# 设置头文件搜索路径
target_include_directories(main
PRIVATE include # 私有头文件目录
# ... 添加其他头文件目录
)
# 添加链接的库文件
target_link_libraries(main
# ${CMAKE_SOURCE_DIR}/libs/some_library.a # 链接第三方库示例
# ... 添加其他需要链接的库
)
add_executable() 方法为,添加项目中的可执行文件路径,即为:main() 方法路径,一个main就添加一个add_executable(),否认则执行会报错。但是也可以配置动态执行表,target_include_directories(),查找项目下的所有main,一劳永逸!
2.3 原子类-节点类
2.3.1 cpp 文件
//
// Created by l on 2023/8/10.
//
#include "Node.h"
Node::Node(int value) {
data = value;
next = nullptr;
}
int Node::getData() const {
return data;
}
Node* Node::getNext() const {
return next;
}
void Node::setNext(Node* node) {
next = node;
}
2.3.2 头文件 -h
//
// Created by l on 2023/8/10.
//
#ifndef NODE_H
#define NODE_H
class Node {
private:
int data; // 节点数据
Node *next; // 指向下一个节点的指针
public:
Node(int value); // 构造函数
int getData() const; // 获取节点数据
Node *getNext() const; // 获取下一个节点指针
void setNext(Node *node); // 设置下一个节点指针
};
#endif
2.4 原子类-链表类
2.4.1 cpp文件
//
// Created by l on 2023/8/10.
//
// LinkedList.cpp
#include "LinkedList.h"
#include <iostream>
LinkedList::LinkedList() {
head = nullptr;
}
LinkedList::~LinkedList() {
clear();
}
void LinkedList::insert(int value) {
Node *first = new Node(value);
if (head == nullptr) {
head = first;
}else{
Node *current = head;
while (current->getNext() != nullptr) {
current = current->getNext();
}
current->setNext(first);
}
}
bool LinkedList::remove(int value) {
Node *first = new Node(value);
if (head->getData() == value) {
delete head;
} else {
Node *current = head;
//获取 目标元素的上一个 元素
while (current->getNext() != first && current->getNext()->getData() != value) {
current = current->getNext();
}
if (current->getNext() != nullptr) {
Node *temp = current->getNext();
current->setNext(temp->getNext());
delete temp;
return true;
}
}
return false;
}
void LinkedList::clear() {
Node *current = head;
//循环查找下一级不为null 的,如果不为null的话,先删除当前元素 ,然后把下一级赋值给当前元素,继续循环找下一级不为null的
while (current->getNext() != nullptr) {
Node *temp = current;
current = current->getNext();
delete temp;
}
head = nullptr;
}
void LinkedList::print() const {
Node *current = head;
while (current->getNext() != nullptr) {
std::cout << current->getData() ;
current = current->getNext();
}
std::cout << current->getData() << std::endl;
}
需要注意的是,c++中传入的是指针,是上一个节点的内存地址;
2.4.2 头文件-h
//
// Created by l on 2023/8/10.
//
// LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h"
class LinkedList {
private:
Node* head; // 头节点指针
public:
LinkedList();
~LinkedList();
void insert(int value);
bool remove(int value);
void clear();
void print() const;
};
#endif
2.5 main
#include <iostream>
#include "linkedList/LinkedList.h"
int main() {
LinkedList linkedList;
// 测试插入和打印操作
std::cout << "Inserting elements: ";
linkedList.insert(5);
linkedList.insert(10);
linkedList.insert(15);
linkedList.print();
// 测试删除和打印操作
std::cout << "Removing element: ";
linkedList.remove(10);
linkedList.print();
// 测试清空和打印操作
std::cout << "Clearing list: ";
linkedList.clear();
linkedList.print();
return 0;
}