单向链表实现头插法、尾插法,实现链表的修改节点和删除节点,实现链表数据在任意位置添加

该代码示例展示了如何在C语言中使用结构体定义链表节点,并实现链表的创建、更新节点值、删除指定节点以及在任意位置插入新节点的功能。主要函数包括create_newNode用于创建新节点,create_list用于创建链表,update_node用于更新节点值,del_node用于删除节点,以及add_node用于在给定数据前插入新节点。
摘要由CSDN通过智能技术生成
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

typedef int dataType;

// 节点
struct node
{
    dataType data;// 指针域
    struct node *next; // 指向下一个节点
};

// 创建新节点
struct node *create_newNode(dataType data)
{
    struct node *pnew = malloc(sizeof(struct node));
    if(pnew == NULL)
        return NULL;

    pnew->data = data;
    pnew->next = NULL;
    return pnew;
}

// 创建链表
struct node *create_list(void)
{
    // 设置空链表
    struct node *head = NULL;
    struct node *tail = NULL;
    while(1)
    {
        dataType data;
        if(scanf("%d",&data) == 0)
            break;
        // 创建新节点
        struct node *pnew = create_newNode(data);
        if(pnew == NULL)
        {
            printf("create new node failed:\n");
            //exit(0); // 不管再哪里调用,整个程序结束
            return NULL; // 只退出本函数
        }
        // 从无到有
        if(head == NULL)
        {
            head = pnew;
            tail = pnew;
            printf("pre:%d\n",head->data);
        }
        else// 从少到多
        {
            #if 1
            // 尾插法
            tail->next = pnew;
            tail = pnew;
            #else
            // 头插法
            pnew->next = head;
            head = pnew;
            #endif
        }
    }

    return head;
}

// 修改节点
struct node *update_node(struct node *head,dataType oldData,dataType newData)
{
    if(head == NULL)
        return NULL;
    
    // 找位置替换
    struct node *p = head;
    while(p)
    {
        if(p->data == oldData)
        {
            p->data = newData;
        }
        else
        {
            p = p->next;
        }
    }
    return head;
}
// 显示链表
void show_list(struct node *head)
{
    if(head == NULL)
        return;

    for(struct node *p = head; p != NULL; p = p->next)
    {
        printf("%d\t",p->data);
    }
    printf("\n");
}

/*
* 功能 :删除一个节点,data对应的是需要删除的节点
* 思路 :定义pre指针指向p的前驱节点,p指向需要删除的节点,注意去头去尾需要防止段错误
*/
struct node *del_node(struct node *head, dataType data)
{
    struct node *p = head;
    struct node *pre = NULL; // 指向p的前一个节点

    // 找节点
    while (p)
    {
        // 找到删除的节点
        if(p->data == data)
        {
            break;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
    
    // 找不到
    if(p == NULL)
    {
        printf("没有需要删除的节点\n");
        return head;
    }
    // 删除的是首节点
    if(p->data == head->data)
    {
        head = p->next;
        p->next = NULL;
        free(p);
    }
    //p是尾节点
    else if(p->next == NULL)
    {
        pre->next = NULL;
        free(p);
    }
    // p是中间节点
    else
    {
        pre->next = p->next;
        p->next = NULL;
        free(p);
    }
    return head;
}

/*
* 任意位置data前面添加新节点newData
* 思路 :1.创建新节点,2.定位p位置
*/

struct node *add_node(struct node *head, dataType newData, dataType data)
{
    // 创建新节点
    struct node *pnew = create_newNode(newData);
    if(pnew == NULL)
        return NULL;

    struct node *p = head;
    struct node *pre = NULL;

    // 找位置
    while (p)
    {
        if(p->data == data)
        {
            break;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
    
    // 找不到
    if(p == NULL)
    {
        // 尾插
        pre->next = pnew;
    }
    else if(head->data == p->data)
    {
        // 头插
        pnew->next = head;
        head = pnew;
    }
    else
    {
        // 中间
        pnew->next = p;
        pre->next = pnew;
    }
    return head;
}

int main(int argc, char const *argv[])
{
    // 创建链表
    struct node *head = create_list();
    if(head == NULL)
        return -1;
    
    // 更新节点
    //head = update_node(head,3,8);

    // 删除节点
    //head = del_node(head,3);

    // 任意位置插入数数据
    head = add_node(head,8,9);

    // 显示链表
    show_list(head);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值