目录
前文、线性表的定义及其基本操作(顺序表插入、删除、查找、修改)
四、线性表的链接存储结构
1. 单链表(C语言)
a. 链表节点结构
b. 创建新节点
c. 在链表末尾插入新节点
d. 删除指定节点
e. 修改指定节点的数据
f. 遍历链表并打印
g. 主函数
C语言代码整合
Cpp代码整合
【数据结构】线性表(一)线性表的定义及其基本操作(顺序表插入、删除、查找、修改)-CSDN博客https://blog.csdn.net/m0_63834988/article/details/132089038?spm=1001.2014.3001.5501
顺序表的优点是存取速度快。但是,无论是插入一个结点,还是删除一个结点,都需要调整一批结点的地址。要克服该缺点,就必须给出一种不同于顺序存储的存储方式。用链接存储方式存储的线性表被称为链表,可以克服上述缺点。
链表中的结点用存储单元(若干个连续字节)来存放,存储单元之间既可以是(存储空间上)连续的,也可以是不连续的,甚至可以零散地分布在存储空间中的任何位置。换言之,链表中结点的逻辑次序和物理次序之间并无必然联系。最重要的是,链表可以在不移动结点位置的前提下根据需要随时添加删除结点,动态调整。
在链接存储结构中,插入和删除操作相对于顺序存储结构而言更加高效,时间复杂度为O(1)。而查找操作的时间复杂度为O(n)。
typedef struct Node {
int data;
struct Node* next;
} Node;
链表节点的结构体 Node
,包含一个整数数据 data
和一个指向下一个节点的指针 next
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode != NULL) {
newNode->data = data;
newNode->next = NULL;
}
return newNode;
}
malloc
分配了节点的内存空间;data
字段,并将 next
字段设置为 NULL。
void insertAtEnd(Node** head, int data) {
Node* newNode = createNode(data);
if (newNode == NULL) {
printf("内存分配失败!\n");
return;
}
if (*head == NULL) {
*head = newNode;
} else {
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
printf("已在链表末尾插入节点:%d", data);
}
createNode
函数创建一个新节点;next
指针指向新节点。void deleteNode(Node** head, int data) {
if (*head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = *head;
Node* prev = NULL;
if (temp != NULL && temp->data == data) {
*head = temp->next;
free(temp);
printf("已删除节点:%d", data);
return;
}
while (temp != NULL && temp->data != data) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
printf("节点 %d 不存在!\n", data);
return;
}
prev->next = temp->next;
free(temp);
printf("已删除节点:%d", data);
}
next
指针,使其跳过要删除的节点,并释放该节点的内存空间。void modifyNode(Node* head, int oldData, int newData) {
if (head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = head;
while (temp != NULL) {
if (temp->data == oldData) {
temp->data = newData;
printf("已将节点 %d 修改为 %d\n", oldData, newData);
return;
}
temp = temp->next;
}
printf("节点 %d 不存在!\n", oldData);
}
查找~删除~修改……这里不重复介绍,懂的都懂,不懂我也没办法
void printList(Node* head) {
if (head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = head;
printf("链表节点数据:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
temp
来遍历链表,依次访问每个节点并打印其数据。nt main() {
Node* head = NULL; // 头节点
insertAtEnd(&head, 1);
insertAtEnd(&head, 2);
insertAtEnd(&head, 3);
printList(head);
deleteNode(&head, 2);
printList(head);
deleteNode(&head, 4);
return 0;
}
head;
insertAtEnd
函数三次,在链表末尾插入了三个节点;printList
函数打印链表的节点数据;deleteNode
函数删除链表中的一个节点,并再次打印链表的节点数据;deleteNode
函数尝试删除一个不存在的节点。#include
#include
// 定义链表节点结构
typedef struct Node {
int data;
struct Node* next;
} Node;
// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode != NULL) {
newNode->data = data;
newNode->next = NULL;
}
return newNode;
}
// 在链表末尾插入新节点
void insertAtEnd(Node** head, int data) {
Node* newNode = createNode(data);
if (newNode == NULL) {
printf("内存分配失败!\n");
return;
}
if (*head == NULL) {
*head = newNode;
} else {
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
printf("已在链表末尾插入节点:%d", data);
}
// 删除指定节点
void deleteNode(Node** head, int data) {
if (*head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = *head;
Node* prev = NULL;
if (temp != NULL && temp->data == data) {
*head = temp->next;
free(temp);
printf("已删除节点:%d", data);
return;
}
while (temp != NULL && temp->data != data) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
printf("节点 %d 不存在!\n", data);
return;
}
prev->next = temp->next;
free(temp);
printf("已删除节点:%d", data);
}
// 修改指定节点的数据
void modifyNode(Node* head, int oldData, int newData) {
if (head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = head;
while (temp != NULL) {
if (temp->data == oldData) {
temp->data = newData;
printf("已将节点 %d 修改为 %d\n", oldData, newData);
return;
}
temp = temp->next;
}
printf("节点 %d 不存在!\n", oldData);
}
// 遍历链表并打印节点数据
void printList(Node* head) {
if (head == NULL) {
printf("链表为空!\n");
return;
}
Node* temp = head;
printf("链表节点数据:");
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
// 主函数测试链表操作
int main() {
Node* head = NULL; // 头节点
insertAtEnd(&head, 1);
insertAtEnd(&head, 2);
insertAtEnd(&head, 3);
printList(head);
deleteNode(&head, 2);
printList(head);
deleteNode(&head, 4);
return 0;
}
与C语言基本相同,这里不再过多介绍
#include
// 定义链表节点结构
class Node {
public:
int data;
Node* next;
// 构造函数
Node(int data) : data(data), next(nullptr) {}
};
// 链表类
class LinkedList {
private:
Node* head;
public:
// 构造函数
LinkedList() : head(nullptr) {}
// 析构函数,用于释放链表内存
~LinkedList() {
Node* current = head;
while (current != nullptr) {
Node* next = current->next;
delete current;
current = next;
}
}
// 在链表末尾插入新节点
void insertAtEnd(int data) {
Node* newNode = new Node(data);
if (head == nullptr) {
head = newNode;
} else {
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = newNode;
}
std::cout << "已在链表末尾插入节点:" << data << std::endl;
}
// 删除指定节点
void deleteNode(int data) {
if (head == nullptr) {
std::cout << "链表为空!" << std::endl;
return;
}
Node* temp = head;
Node* prev = nullptr;
if (temp != nullptr && temp->data == data) {
head = temp->next;
delete temp;
std::cout << "已删除节点:" << data << std::endl;
return;
}
while (temp != nullptr && temp->data != data) {
prev = temp;
temp = temp->next;
}
if (temp == nullptr) {
std::cout << "节点 " << data << " 不存在!" << std::endl;
return;
}
prev->next = temp->next;
delete temp;
std::cout << "已删除节点:" << data << std::endl;
}
// 修改指定节点的数据
void modifyNode(int oldData, int newData) {
if (head == nullptr) {
std::cout << "链表为空!" << std::endl;
return;
}
Node* temp = head;
while (temp != nullptr) {
if (temp->data == oldData) {
temp->data = newData;
std::cout << "已将节点 " << oldData << " 修改为 " << newData << std::endl;
return;
}
temp = temp->next;
}
std::cout << "节点 " << oldData << " 不存在!" << std::endl;
}
// 遍历链表并打印节点数据
void printList() {
if (head == nullptr) {
std::cout << "链表为空!" << std::endl;
return;
}
Node* temp = head;
std::cout << "链表节点数据:";
while (temp != nullptr) {
std::cout << temp->data << " ";
temp = temp->next;
}
std::cout << std::endl;
}
};
int main() {
LinkedList list;
list.insertAtEnd(1);
list.insertAtEnd(2);
list.insertAtEnd(3);
list.printList();
list.deleteNode(2);
list.printList();
list.deleteNode(4);
return 0;
}