C语言:数据结构链表基本操作(增、删、改、查、遍历)
成为你的Bug 2024-10-16 11:35:02 阅读 97
一、数据结构-链表介绍
链表:在物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。由一系列节点(链表中每一个元素称为节点/结点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。
链表可以分为单向链表和双向链表两种形式。在单向链表中,每个节点只保存指向下一个节点的指针,而在双向链表中,每个节点同时保存指向上一个节点和下一个节点的指针。
二、链表操作
插入:在链表的任意位置插入一个节点;删除:从链表中删除一个节点;查找:在链表中查找指定的数据;修改:修改链表中节点的数据;遍历:按照顺序依次访问链表中的每个节点。
三、创建和释放
1. 创建节点
<code>// 创建一个新节点
Node* createNode(ElemType data)
{
Node* newNode = (Node*)malloc(sizeof(Node));
if(newNode != NULL)
{
newNode -> data = data; // 设置数据
newNode -> next = NULL; // 新节点的下一个节点为空
}
return newNode;
}
2. 创建空链表
// 创建一个空链表
linkedList* createLinkedList()
{
linkedList* list = (linkedList*)malloc(sizeof(linkedList));
if(list != NULL)
{
list -> head = NULL; // 头指针为空
list -> length = 0; // 链表长度为0
}
return list;
}
3. 释放空间
// 释放链表的内存
void freeLinkedList(linkedList* list)
{
if(list == NULL)
return;
Node* current = list -> head;
while(current != NULL)
{
Node* temp = current;
current = current -> next;
free(temp); // 释放节点内存
}
free(list); // 释放链表内存
}
四、链表操作各部分代码实现
1. 插入
// 在链表的指定位置插入节点
void insertNode(linkedList* list, int pos, ElemType data)
{
if(list == NULL || pos < 0 || pos > list -> length)
return;
Node* newNode = createNode(data); // 创建新节点
if(newNode == NULL)
return;
if(pos == 0)
{
newNode -> next = list -> head; // 将新节点插入到链表头部
list -> head = newNode; // 更新头指针
}
else
{
Node* current = list -> head;
for(int i =0; i < pos - 1; i++) // 找到插入位置的前一个节点
{
current = current -> next;
}
newNode -> next = current -> next; // 新节点指向原来位置的节点
current -> next = newNode; // 前一个节点指向新节点
}
list -> length ++; // 链表长度加 1
}
2. 删除
// 删除链表的指定位置的节点
void deleteNode(linkedList* list, int pos)
{
if(list == NULL || pos < 0 || pos >= list -> length)
return;
Node* temp;
if(pos == 0)
{
temp = list -> head; // 保存头节点
list -> head = list -> head -> next; // 更新头指针
}
else
{
Node* current = list -> head;
for(int i = 0; i < pos - 1; i++) // 找到要删除节点的前一个节点
{
current = current -> next;
}
temp = current -> next; // 保存要删除的节点
current -> next = temp -> next; // 前一个节点指向要删除节点的下一个节点
}
free(temp); // 释放节点内存
list -> length--; // 链表长度减1
}
3. 修改
// 查找链表中指定数据的位置
int findNode(linkedList* list, ElemType data)
{
if(list == NULL)
return -1;
Node* current = list -> head;
int pos = 0;
while(current != NULL) // 遍历链表
{
if(current -> data == data) // 找到数据相同的节点
return pos;
current = current -> next;
pos++;
}
return -1; // 数据不存在
}
4. 查找
// 查找链表中指定数据的位置
int findNode(linkedList* list, ElemType data)
{
if(list == NULL)
return -1;
Node* current = list -> head;
int pos = 0;
while(current != NULL) // 遍历链表
{
if(current -> data == data) // 找到数据相同的节点
return pos;
current = current -> next;
pos++;
}
return -1; // 数据不存在
}
5. 遍历
// 遍历,打印链表的所有节点数据
void printLinkedList(linkedList* list)
{
if(list == NULL)
return;
Node* current = list -> head;
while(current != NULL)
{
printf("%d ",current -> data);
current = current -> next;
}
printf("\n");
}
五、完整代码
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
// 定义链表节点
typedef struct Node{
ElemType data;
struct Node* next;
}Node;
// 定义链表结构
typedef struct{
Node* head; // 头指针
int length; // 链表长度
}linkedList;
// 创建一个新节点
Node* createNode(ElemType data)
{
Node* newNode = (Node*)malloc(sizeof(Node));
if(newNode != NULL)
{
newNode -> data = data; // 设置数据
newNode -> next = NULL; // 新节点的下一个节点为空
}
return newNode;
}
// 创建一个空链表
linkedList* createLinkedList()
{
linkedList* list = (linkedList*)malloc(sizeof(linkedList));
if(list != NULL)
{
list -> head = NULL; // 头指针为空
list -> length = 0; // 链表长度为0
}
return list;
}
// 在链表的指定位置插入节点
void insertNode(linkedList* list, int pos, ElemType data)
{
if(list == NULL || pos < 0 || pos > list -> length)
return;
Node* newNode = createNode(data); // 创建新节点
if(newNode == NULL)
return;
if(pos == 0)
{
newNode -> next = list -> head; // 将新节点插入到链表头部
list -> head = newNode; // 更新头指针
}
else
{
Node* current = list -> head;
for(int i =0; i < pos - 1; i++) // 找到插入位置的前一个节点
{
current = current -> next;
}
newNode -> next = current -> next; // 新节点指向原来位置的节点
current -> next = newNode; // 前一个节点指向新节点
}
list -> length ++; // 链表长度加 1
}
// 删除链表的指定位置的节点
void deleteNode(linkedList* list, int pos)
{
if(list == NULL || pos < 0 || pos >= list -> length)
return;
Node* temp;
if(pos == 0)
{
temp = list -> head; // 保存头节点
list -> head = list -> head -> next; // 更新头指针
}
else
{
Node* current = list -> head;
for(int i = 0; i < pos - 1; i++) // 找到要删除节点的前一个节点
{
current = current -> next;
}
temp = current -> next; // 保存要删除的节点
current -> next = temp -> next; // 前一个节点指向要删除节点的下一个节点
}
free(temp); // 释放节点内存
list -> length--; // 链表长度减1
}
// 更新链表的指定位置的节点数据
void updateNode(linkedList* list, int pos, ElemType data)
{
if(list == NULL || pos < 0 || pos >= list -> length)
return;
Node* current = list -> head;
for(int i = 0; i < pos; i++) // 找到要更新的节点
{
current = current -> next;
}
current -> data = data; // 更新节点数据
}
// 查找链表中指定数据的位置
int findNode(linkedList* list, ElemType data)
{
if(list == NULL)
return -1;
Node* current = list -> head;
int pos = 0;
while(current != NULL) // 遍历链表
{
if(current -> data == data) // 找到数据相同的节点
return pos;
current = current -> next;
pos++;
}
return -1; // 数据不存在
}
// 遍历,打印链表的所有节点数据
void printLinkedList(linkedList* list)
{
if(list == NULL)
return;
Node* current = list -> head;
while(current != NULL)
{
printf("%d ",current -> data);
current = current -> next;
}
printf("\n");
}
// 释放链表的内存
void freeLinkedList(linkedList* list)
{
if(list == NULL)
return;
Node* current = list -> head;
while(current != NULL)
{
Node* temp = current;
current = current -> next;
free(temp); // 释放节点内存
}
free(list); // 释放链表内存
}
int main()
{
linkedList* list = createLinkedList(); // 创建一个链表
insertNode(list, 0, 10);
insertNode(list, 1, 20);
insertNode(list, 2, 30);
printLinkedList(list);
updateNode(list, 1, 25);
printLinkedList(list);
deleteNode(list, 2);
printLinkedList(list);
int pos = findNode(list, 30);
printf("pos = %d\n", pos);
freeLinkedList(list);
return 0;
}
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。