单链表的头插、中插、尾插、删除、逆序、显示(C语言实现)

单链表的定义:

单链表是一种顺序存储的结构。
有一个头结点,没有值域,只有连域,专门存放第一个结点的地址。
有一个尾结点,有值域,也有链域,链域值始终为NULL。
所以,在单链表中为找第i个结点或数据元素,必须先找到第i - 1 结点或数据元素,而且必须知道头结点,否者整个链表无法访问。


单链表的综合操作:

这里写图片描述

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

/* 创建一个节点,并为这个节点起一个别名Node */
typedef struct node
{
    int num;

    struct node * next;
}Node;

typedef Node * link;

/* 创建无表头单链表 */
void create_link(link * head)
{
    *head = NULL;
}

/* 单链表的头插 */
void insert_head_node(link * newnode, link * head)
{
    (*newnode)->next = * head;
    * head = (*newnode);
}

/* 单链表的中插 */
int insert_mid_node(int num, link *newnode, link * head)
{
    if (*head == NULL)
    {
        return -1;
    }

    link temp = *head;
    while (temp != NULL)
    {
        if (temp->num == num)
        {
            (*newnode)->next = temp->next;
            temp->next = (*newnode);
            return 0;
        }
        temp = temp->next;
    }
    return -1;
}

/* 单链表的尾插 */
void insert_tail_node(link * newnode, link * head)
{
    link temp = *head;

    if (*head == NULL)
    {
        (*newnode)->next = NULL;
        *head = *newnode;
    }
    else
    {
        while (temp->next != NULL)
        {
            temp = temp->next;
        }

        temp->next = *newnode;
        (*newnode)->next = NULL;
    }
}

/*单链表的遍历显示*/
void display_node(link * head)
{
    link temp = * head;

    while (temp != NULL)
    {
    printf("%d\n", temp->num);

    temp = temp->next;
    }

}

/* 单链表的删除 */
int delete_node(int dnum, link *head)
{
    if (*head == NULL)
    {
        return -1;
    }
    link temp = *head;

    if ((*head)->num == dnum)
    {
        (*head) = (*head)->next;
        free (temp);
        temp = NULL;
        return 0;
    }

    link d_temp = temp;
    temp = temp->next;

    while (temp != NULL)
    {
        if ((temp->num) == dnum)
        {
            d_temp->next = temp->next;
            free(temp);
            temp = NULL;
            return 0;
        }
        d_temp =temp;
        temp = temp->next;
    }
}

/* 单链表的逆序 */
int reverse_node(link *head)
{
    if (*head == NULL)
    {
        return -1;
    }
    if ((*head)->next == NULL)
    {
        return -1;
    }
    link str = *head;
    link ptr = str->next;
    link temp = ptr->next;

    while (temp != NULL)
    {
        ptr->next = str;
        str = ptr;
        ptr = temp;
        temp = temp->next;
    }

    ptr->next = str;
    (*head)->next = NULL;
    *head = ptr;
}

/* 主函数 */
int main()
{
    int i;
    int set;       /* 想要插入(中插)的位置 */
    int likenum;   /* 想要插入(中插)的元素 */
    int deletenum; /* 想要删除的元素 */

    link head;
    link newnode;
    /* 创建单链表 */
    create_link(&head);

    /* 循环插入十个元素 */
    for (i = 0; i < 10; i++)
    {
        newnode = (link)malloc(sizeof(Node));
        if (newnode == NULL)
        {
            printf("malloc newnode error!\n");
        }

        newnode->num = i + 1;
        /*下面的头插和尾插方式选择一种就可以了
          一般的头插得到的序列是反的
          所以我们一般采用尾插*/
        //insert_head_node(&newnode, &head);  //头插
        insert_tail_node(&newnode, &head);    //尾插
    }

    printf("1-10 link is\n");
    display_node(&head);

    printf("the reverse link following:\n");
    reverse_node(&head);
    display_node(&head);

    newnode = (link)malloc(sizeof(Node));
    printf("please input your like number!\n");
    scanf("%d", &likenum);
    newnode->num = likenum;

    printf("please input number (only 1-10)\n");
    scanf("%d",&set);
    insert_mid_node(set, &newnode, &head);    //中插

    printf("the insert result is:\n");
    display_node(&head);

    printf("please input you want to delete num!\n");
    scanf("%d",&deletenum);

    delete_node(deletenum, &head);

    printf("The delete result is\n");
    display_node(&head);

    return 0;
}

运行结果

这里写图片描述
这里写图片描述

此代码是我写的一个单链表的demo可以直接复制运行。

如果你对这方面不懂的或者初学者。可以用这个demo自己改装做一个通讯录管理系统。将结构体扩大不仅仅存储num。存储学生信息,传递结构体即可,相信做完你会有更大的进步。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxnsirius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值