链表的常用函数

#include <stdio.h>  
#include <stdlib.h>  

// 定义链表节点  
typedef struct ListNode {
    int value;          // 节点存储的数据  
    struct ListNode* next;  // 指向下一个节点的指针  
} ListNode;



//通常,链表通过一个指向其第一个节点的指针来表示。
// 创建空链表  
ListNode* List_create() {
    return NULL; // 空链表就是返回NULL  
}



// 在链表末尾添加元素  
void List_End_appendNode(ListNode** head, int newValue) {
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); // 创建新节点  
    if (newNode == NULL) {
        printf("Memory allocation failed\n");
        return;
    }
    newNode->value = newValue;
    newNode->next = NULL;

    if (*head == NULL) {
        // 如果链表为空,新节点即为头节点  
        *head = newNode;        //改变了头节点的地址
    }                           //*head存储的是链表的头地址
    else {
        // 否则,遍历到链表末尾,将新节点添加进去  
        ListNode* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }
}



//在链表开头添加元素
void List_Head_appendNode(ListNode** head, int newValue) {
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); // 创建新节点
    if (newNode == NULL) {
        printf("Memory allocation failed\n");   //判断内存是否分配成功
        return;
    }
    newNode->value = newValue;
    newNode->next = *head;
    *head = newNode;
}



// 遍历链表并打印  
void List_Print(ListNode* head) {    //传入的参数是结构体类型的指针,也是链表开头结构体的指针,所以也可以说是传入了链表
    ListNode* current = head;
    while (current != NULL) {
        printf("%d -> ", current->value);
        current = current->next;
    }
    printf("NULL\n");
}



//拼接链表
void List_Link(ListNode** head_1, ListNode** head_2) {
    if (head_1 == NULL || *head_1 == NULL || head_2 == NULL || *head_2 == NULL) {
        // 处理空指针的情况,比如打印错误信息或设置错误代码  
        return;
    }
    ListNode* current = *head_1;
    while (current->next != NULL) {
        current = current->next;
    }
    current->next = *head_2;
}



//尾删节点
//要删除链表的最后一个节点,你需要访问倒数第二个节点(即最后一个节点的前一个节点),
// 并将其 next 指针设置为 NULL.
void List_End_Delete(ListNode** head) {
    if (head == NULL || *head == NULL || (*head)->next == NULL) {
        // 处理空指针的情况,比如打印错误信息或设置错误代码  
        return;
    }
    ListNode* current = *head;
    ListNode* prev = NULL;    // 用于追踪current的前一个节点  
    while (current->next != NULL) {
        prev = current;
        current = current->next;
    }
    // 此时current指向链表的最后一个节点  
    // prev指向链表的倒数第二个节点  
    // 将prev的next指针设置为NULL,从而从链表中删除最后一个节点  
    prev->next = NULL;
    free(current);
}



//头删节点
void List_Head_Delete(ListNode** head) {
    // 检查头指针是否为空或链表是否为空  
    if (head == NULL || *head == NULL) {
        // 处理空指针或空链表的情况  
        printf("The list is empty");    // 这里可以选择打印错误信息或设置错误代码,但通常不需要删除操作  
        return;
    }

    // 至少有一个节点需要被删除  
    ListNode* first_node = *head; // 保存头节点的指针  
    *head = first_node->next; // 更新头指针,使其指向下一个节点  

    // 释放原头节点的内存  
    free(first_node);

    // 注意:这里不需要检查 (*head)->next == NULL,因为即使链表只有一个节点,  
    // 在更新头指针后,head 将指向 NULL,这是正确的。  
    // 如果链表原本为空(即 *head == NULL),则不会执行到 free(first_node); 这行代码。  
}



//清空链表
void List_Empty(ListNode** head) {
    // 检查头指针是否为空或链表是否为空  
    if (head == NULL || *head == NULL) {
        // 处理空指针或空链表的情况  
        printf("The list is empty");    // 这里可以选择打印错误信息或设置错误代码,但通常不需要删除操作  
        return;
    }
    ListNode* current = *head;
    while (current->next != NULL) {
        current->value = 0;
        current = current->next;
    }
}



//链表反转
void List_reversal(ListNode** head) {

    ListNode* prev = NULL; // 前一个节点地址,初始化为NULL  
    ListNode* current = *head; // 当前节点地址,初始化为头节点

    // 遍历链表,直到current为NULL  
    while (current != NULL) {
        ListNode* next = current->next; // 保存下一个节点的指针 

        current->next = prev;   // 反转当前节点的next指针 

        prev = current;     // 移动prev和current指针 
        current = next;
    }
    *head = prev;   // 当遍历完成时,prev将指向新的头节点
}



// 插入排序函数 ,根据value排序
void List_insertionSort(ListNode** head) {
    ListNode* sorted = NULL; // 初始化一个空的已排序链表  
    ListNode* current = *head;
    while (current != NULL) {
        ListNode* nextTemp = current->next; // 保存当前节点的下一个节点  

        // 将当前节点插入到已排序链表中的正确位置,此时current->next会变更,不在与原链表连接
        if (sorted == NULL || sorted->value >= current->value) {
            // 如果已排序链表为空,或者当前节点应该插入到已排序链表的头部  
            current->next = sorted;
            sorted = current;
        }
        else {
            // 否则,在已排序链表中查找插入位置  
            ListNode* prev = NULL;
            ListNode* temp = sorted;
            while (temp != NULL && temp->value < current->value) {
                prev = temp;
                temp = temp->next;
            }
            prev->next = current; // 将当前节点插入到正确位置  
            current->next = temp;
        }

        current = nextTemp; // 移动到原始链表的下一个节点  
    }

    *head = sorted; // 更新头指针  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值