链表创建 删除 插入 逆置 打印 释放内存

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

//定义类型
typedef struct Stlianbiao
{
    char name[20];
    struct Stlianbiao *next;
}SLB;

void createLB(SLB **head)
{
    //定义辅助指针
    SLB *p = NULL;
    SLB *cur = NULL;
    SLB *c = NULL;
    //定义接受字符串变量
    char name[20];
    //判断指针是否合法
    if (head == NULL)
    {
        printf("createLB ERROR..");
        return;
    }
    //分配头指针内存
    p = (SLB *)malloc(sizeof(SLB));
    memcpy(p->name, "head", 20);
    p->next = NULL;
    //赋值当前指针
    cur = p;
    printf("ENTER A NAME TO CREATE A BL,0 TO EXIT:");
    //输出姓名
    scanf("%s", name);
    //当输入字符串为0时候停止循环
    while (strcmp(name,"0") != 0)
    {
        //分配内存
        c = (SLB *)malloc(sizeof(SLB));
        memcpy(c->name, name, sizeof(name));
        c->next = NULL;
        //连接
        cur->next = c;
        //移动当前指针
        cur = c;
        //下一项
        printf("ENTER A NAME TO CREATE A BL,0 TO EXIT:");
        //输出姓名
        scanf("%s", name);
    }
    //指针作输出
    *head = p;
}

//删除指定项
void delLB(SLB *head,char *name)
{
    //定义辅助指针
    SLB * cur = NULL, *pre = NULL;
    //判断指针是否合法
    if (head == NULL)
    {
        printf("delLB ERROR..");
        return;
    }
    pre = head;
    cur = head->next;
    while (cur)
    {
        //如果找到指定项则删除并中断循环
        if (!strcmp(cur->name,name))
        {
            pre->next = cur->next;
            free(cur);
            break;
        }
        //移动辅助指针
        pre = cur;
        cur = pre->next;
    }
}

//在指定项面前插入项 如果没有指定项则在最后插入项
void insertLB(SLB *head, char *name,char *in)
{
    //定义辅助指针
    SLB * cur = NULL, *pre = NULL,*c =NULL;
    //判断指针是否合法
    if (head == NULL)
    {
        printf("insertLB ERROR..");
        return;
    }
    pre = head;
    cur = head->next;
    while (cur)
    {
        //当前项是要找的项则退出遍历
        if (!strcmp(cur->name, name))
        {
            break;
        }
        //移动指针
        pre = cur;
        cur = pre->next;
    }
    //分配内存
    c = (SLB *)malloc(sizeof(SLB));
    memset(c->name, 0, 20);
    memcpy(c->name, in, 20);
    //插入操作
    c->next = cur;
    pre->next = c;
}

//遍历打印链表
void printLB(SLB *head)
{
    //判断指针是否合法
    if (head == NULL)
    {
        printf("printLB ERROR..");
        return;
    }
    //开始打印
    printf("START ");
    head = head->next;
    while (head)
    {
        printf("%s ", head->name);
        //移动指针
        head = head->next;
    }
    //结束打印
    printf(" END
");
}

//释放内存
void freeLB(SLB **head)
{
    //当前指针
    SLB * cur = NULL;
    //判断指针是否合法
    if ((*head) == NULL)
    {
        printf("freeLB ERROR..");
        return;
    }
    //释放后面的项
    cur = (*head)->next;
    while (cur)
    {
        //断开当前指针 连接应当相邻指针
        (*head)->next = cur->next;
        //释放当前指针
        free(cur);
        //移动当前指针
        cur = (*head)->next;
    }
    //释放头指针
    free(*head);
    //避免野指针
    *head = NULL;
}

//链表逆置
void reverseLB(SLB *head)
{
    //定义辅助指针 temp缓存指针
    SLB * temp = NULL, *p = NULL, *q = NULL;
    //头指针为空错误
    if (head == NULL)
    {
        printf("reverseLB ERROR..");
        return;
    }
    //只有一项一下则不需要逆置
    if (head->next == NULL || head->next->next == NULL)
    {
        printf("reverseLB is the same..");
        return;
    }
    //p q分别为第一 第二项
    p = head->next;
    q = p->next;
    while (q != NULL)
    {
        //缓存下一项
        temp = q->next;
        //逆置
        q->next = p;
        //移动指针
        p = q;
        q = temp;
    }
    //处理剩余的
    head->next->next = NULL;
    head->next = p;
}

void main()
{
    //定义一个头指针
    SLB *head = NULL;
    //指针作输出 创建头指针并创建链表
    createLB(&head);
    printLB(head);

    //链表逆置
    reverseLB(head);
    printLB(head);

    //删除 删除链表中名字为20的项
    delLB(head, "20");
    printLB(head);

    //插入 在30之前插入300 如果不存在30则在最后插入300
    insertLB(head, "30", "300");
    printLB(head);

    //插入 在200之前插入20000 如果不存在30则在最后插入300
    insertLB(head, "200", "20000");
    printLB(head);

    //释放内存 用二级指针 避免野指针
    freeLB(&head);
    system("pause");
}

原文地址:https://www.cnblogs.com/godehi/p/8535019.html