C语言中的链表操作

在C语言中,链表是一种常见的数据结构,它通过节点(Node)的集合来表示序列,其中每个节点都包含数据部分和指向下一个节点的指针(或链接)。链表操作主要包括创建链表、插入节点、删除节点、查找节点、遍历链表等。使用链表可以实现栈或队列、哈希表、图等其他复杂数据结构。

创建链表

创建链表通常需要先定义节点结构体、随后初始化头指针并逐个创建并链接节点,节点结构体通常包含至少两个成员:一个是存储数据的数据域,另一个是存储指向下一个节点指针的指针域。

定义表示链表中的节点结构体的方法如下:

typedef struct Node {
    
      
    int data; // 节点存储的数据  
    struct Node* next; // 指向下一个节点的指针  
} Node;  

创建空链表并返回链表的头指针的方法函数如下:

Node* createList() {
    
      
    Node* head = NULL; // 初始化头指针为NULL,表示创建一个空链表  
    return head; // 返回头指针  
}

插入节点

在链表中插入节点通常涉及到找到插入位置的前一个节点,然后改变指针的指向以包含新节点。插入操作可以分为头插法、尾插法和在指定位置插入。

头插法:新节点插入到链表头部。

void AtHead(Node** head, int newData) {
    
      
    Node* newNode = (Node*)malloc(sizeof(Node));  
    newNode->data = newData;  
    newNode->next = *head;  
    *head = newNode;  
}  

尾插法:新节点插入到链表尾部,需要维护一个尾指针来简化操作。

void insertAtTail(Node** head, int newData) {
    
      
    Node* newNode = (Node*)malloc(sizeof(Node));  
    newNode->data = newData;  
    newNode->next = NULL;  
    if (*head == NULL) {
    
      
        *head = newNode;  
        return;  
    }  
    Node* last = *head;  
    while (last->next != NULL) {
    
      
        last = last->next;  
    }  
    last->next = newNode;  
} 

在指定位置插入:找到指定位置的前一个节点,然后插入新节点。

void insertAtPosition(Node** head, int newData, int position) {
    
      
    if (position == 0) {
    
      
        insertAtHead(head, newData);  
        return;  
    }  
    Node* newNode = (Node*)malloc(sizeof(Node));  
    newNode->data = newData;  
    newNode->next = NULL;  
    if (*head == NULL) {
    
      
        *head = newNode;  
        return;  
    }  
    Node* temp = *head;  
    for (int i = 0; temp != NULL && i < position - 1; i++) {
    
      
        temp = temp->next;  
    }  
    if (temp == NULL) {
    
      
        free(newNode); // 位置无效的话就释放新节点并返回  
        return;  
    }  
    newNode->next = temp->next;  
    temp->next = newNode;  
}  
  

删除节点

删除链表中的节点通常涉及到找到要删除的节点的前一个节点,然后改变其指针域以跳过要删除的节点,如果删除的是头节点,则需要特别处理,因为头指针本身可能需要改变。

void deleteNode(Node** head, int key) {
    
    
    Node* temp = *head, *prev = NULL;
    if (temp != NULL && temp->data == key) {
    
    
        *head = temp->next; // 头节点就是要删除的节点,比如删除key节点
        free(temp);
        return;
    }
    while (temp != NULL && temp->data != key) {
    
    
        prev = temp;
        temp = temp->next;
    }
    if (temp == NULL) return; // 没有找到要删除的节点
    prev->next = temp->next;
    free(temp);
}

查找节点及遍历链表

查找链表中的节点通常涉及遍历链表,比较每个节点的数据域直到找到所需的节点或遍历完整个链表。查找操作可以返回节点的指针或节点的位置。

Node* findNode(Node* head, int value) {
    
      
    Node* temp = head;  
    while (temp != NULL) {
    
      
        if (temp->data == value) {
    
      
            return temp; // 找到节点并返回节点的指针  
        }  
        temp = temp->next; // 继续遍历链表  
    }  
    return NULL; // 没有找到节点就返回NULL  
} 

综合示例

#include <stdio.h>  
#include <stdlib.h>  
  
// 定义链表节点结构体  
typedef struct Node {
    
      
    int data;  
    struct Node* next;  
} Node;  
  
// 创建新节点  
Node* createNode(int data) {
    
      
    Node* newNode = (Node*)malloc(sizeof(Node));  
    if (newNode == NULL) {
    
      
        printf("Memory allocation failed.\n");  
        exit(1);  
    }  
    newNode->data = data;  
    newNode->next = NULL;  
    return newNode;  
}  
  
// 头插法
void insertAtHead(Node** head, int data) {
    
      
    Node* newNode = createNode(data);  
    newNode->next = *head;  
    *head = newNode;  
}  
  
// 尾插法  
void insertAtTail(Node** head, int data) {
    
      
    Node* newNode = createNode(data);  
    if (*head == NULL) {
    
      
        *head = newNode;  
        return;  
    }  
    Node* temp = *head;  
    while (temp->next != NULL) {
    
      
        temp = temp->next;  
    }  
    temp->next = newNode;  
}  
  
// 删除链表中第一个数据域为指定值的节点的函数  
void deleteNode(Node** head, int data) {
    
      
    Node* temp = *head;  
    Node* prev = NULL;  
    while (temp != NULL && temp->data != data) {
    
      
        prev = temp;  
        temp = temp->next;  
    }  
    if (temp == NULL) {
    
     
        return;  
    }  
    if (prev == NULL) {
    
     
        *head = temp->next;  
    } else {
    
     
        prev->next = temp->next;  
    }  
    free(temp);  
}  
  
// 返回链表中第一个数据域为指定值的节点的指针的函数
Node* findNode(Node* head, int data) {
    
      
    Node* temp = head;  
    while (temp != NULL) {
    
      
        if (temp->data == data) {
    
      
            return temp;  
        }  
        temp = temp->next;  
    }  
    return NULL;  
}  
  
// 打印链表的函数  
void printList(Node* head) {
    
      
    Node* temp = head;  
    while (temp != NULL) {
    
      
        printf("%d -> ", temp->data);  
        temp = temp->next;  
    }  
    printf("NULL\n");  
}  
  
// 释放链表内存的函数  
void freeList(Node* head) {
    
      
    Node* temp;  
    while (head != NULL) {
    
      
        temp = head;  
        head = head->next;  
        free(temp);  
    }  
}  
  
int main() {
    
      
    Node* head = NULL;  
      
    // 插入节点  
    insertAtHead(&head, 3);  
    insertAtHead(&head, 2);  
    insertAtHead(&head, 1);  
    insertAtTail(&head, 4);  
    printList(head); // 调用函数打印链表
      
    // 删除节点  
    deleteNode(&head, 3);  
    printList(head); 
      
    // 查找节点  
    Node* foundNode = findNode(head, 2);  
    if (foundNode != NULL) {
    
      
        printf("Found node with data: %d\n", foundNode->data);  
    } else {
    
      
        printf("Node with data 2 not found.\n");  
    }  
      
    // 释放链表内存  
    freeList(head);  
      
    return 0;  
}

代码输出:

1 -> 2 -> 3 -> 4 -> NULL
1 -> 2 -> 4 -> NULL
Found node with data: 2

猜你喜欢

转载自blog.csdn.net/m0_73500130/article/details/140085255
今日推荐