欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一篇看懂链表增删改查(文末附完整文件可直接cv大法调试)

程序员文章站 2022-03-03 08:33:41
...

链表创建及功能实现
QT旧版本没搞明白怎么支持输出中文所以只能拿出散装英语了= =
语法错误勿怪哈~

ps:关于尾指针的一些心得

在头指针创建后,尾指针也创建了(其实都是一个节点指针的变量,只是头指针分配了内存,尾指针没有分配,只是一个指针变量),并指向头指针,这时候只有一个头指针,所以尾指针将指针域设置为NULL,也就是头指针的指针域设置为NULL,当要执行添加操作时,尾指针就像一个帽子,趴在目前最近的节点头上,看到NEW了一个新的节点,就将身下的节点的指针域由NULL改为NEW的节点的地址,然后喊NEW的节点把自己的指针域改为NULL,然后脱离目前这个节点-,跳到NEW的那个节点的头上,完成添加操作。

createList创建链表

//创建链表
PNODE createList()
{
    int len;    //有效节点的个数
    int val;    //存放临时数据

    PNODE pHead = (PNODE)malloc(sizeof(Node));
    if(NULL == pHead)
    {
        printf("malloc failed \n");
        exit(-1);
    }
//因为还没有新的节点,这时候尾指针和头指针指向同一个内存  
    pTail->pNext = NULL;

    printf("The len you need is: ");
    scanf("%d", &len);

    //对链表进行初始化,为所创建的len长度的链表分配内存并赋值
    for(int i=0; i<len; i++)
    {
        //printf里面的%d都是为逗号,后面的值服务的,在输出的时候%d就会替换为逗号后面的值,这里是逗号后面的值给前面的%d
        printf("Please enter no.%d segment val: ", i+1);
        //scanf这里是输出,是%d的值给后面的val,和printf的方向相反,这里把输入的值传递给变量val
        scanf("%d", &val);

        //为新节点分配空间
        PNODE pNew  = (PNODE)malloc(sizeof(NODE));
        {
            if(NULL == pNew)
            {
                printf("failed \n");
                exit(-1);
            }
        }
        pNew->data = val;

        pTail->pNext = pNew;
        pNew->pNext = NULL;
        pTail = pNew;

    }
    return pHead;
}

遍历并输出链表内容

//遍历并输出链表内容
void traverse_list(PNODE pHead)
{
    PNODE p = pHead->pNext;
    printf("the value of the whole list now is :");
    while(NULL != p->pNext)
    {
        printf("%d ", p->data);

        p = p->pNext;
    }
    //如果p为尾节点了,就把这最后一个p的数据打印出来然后换行
    printf("%d \n \n", p->data);

    return;
}

尾部追加

//尾部追加
void append_list(PNODE pHead)
{
    int val;
    PNODE p = pHead->pNext;
    while(NULL != p->pNext)
    {
        p = p->pNext;
    }

    //创建一个新的节点
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(pNew == NULL)
    {
        printf("append failed \n");
    }
    printf("scanf the data you want to append: ");
    //想要给这个变量传值就要取地址,因为这是一个临时变量而非指针
    scanf("%d", &val);

    pNew->data = val;
    //跳出循环时p就指向最后一个节点
    p->pNext = pNew;
    pNew->pNext = NULL;

   return;
}

删除指定位置节点

//删除指定位置(首节点为1)
void delete_list(PNODE pHead)
{
    int pos;
    int i = 1;

    printf("where the  position is  you want to delete? ");
    scanf("%d", &pos);

    PNODE q = pHead;
    PNODE p = q->pNext;
    while(i != pos)
    {
        q = q->pNext;
        p = p->pNext;
        i++;
    }
    if(p->pNext == NULL)
    {
        printf("the val you delete is: %d \n", p->data);
        q->pNext = NULL;
        free(p);
    }
    else
    {
        printf("the val you delete is: %d \n", p->data);
        q->pNext = p->pNext;
        free(p);
    }
    return;
}

指定位置插入节点

void insert_list(PNODE pHead)
{
    int pos;
    int i = 1;
    int val;

    PNODE q = pHead;
    PNODE p = q->pNext;

    printf("where the  position is  you want to insert? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    //当i不等于pos时,这里的i和pos是位置相等的,讲这个判断写在printf和scanf之间是为了能在外界输入pos按下回车后
    //如果超过边界了就立即报错,就不进到输入数值的环节了,这样能进入到输入数值那pos就没问题
    while(i != pos)
    {
        q = q->pNext;
        p = p->pNext;

        //这里是判断是否输入的pos超过了已有数组有效场地的最大值,也就是i
        if(p == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }
        i++;
    }

    printf("what the  val do you want to insert? ");
    scanf("%d", &val);

    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    pNew->data = val;

    //排除了超过边界的pos值输入后,所有的pNew一定都是在pHead和p之间插入的,就算一共有3个元素,pos填3,那pNew就在第三,p指针移到第4
    //如果pos填4,则报警
    q->pNext = pNew;
    pNew->pNext = p;

    return;
}

修改指定位置节点的值

//修改指定位置的节点的值
void change_list(PNODE pHead)
{
    //q指向首节点(如果首节点不存在则指向NULL)
    PNODE q = pHead->pNext;
    int pos;
    int i = 1;
    int val;

    printf("Which node do you want to modify the value? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    while(i != pos)
    {
        q = q->pNext;

        if(q == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }

        i++;
    }
    printf("What the value do you want to set? ");
    scanf("%d", &val);
    q->data = val;
}

查找指定位置节点的值

void findByPos_list(PNODE pHead)
{
    //q指向首节点(如果首节点不存在则指向NULL)
    PNODE q = pHead->pNext;
    int pos;
    int i = 1;

    printf("Which node do you want to query the value? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    while(i != pos)
    {
        q = q->pNext;

        if(q == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }

        i++;
    }
    printf("the value at position %d is: %d \n", i,q->data);
}

完整代码:

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

#include <QCoreApplication>

typedef struct Node
{
    int data; //数据域
    struct Node * pNext; //指针域
}NODE, *PNODE; //NODE等价于struct Node    PNODE等价于struct Node *


//创建链表
PNODE createList();
//遍历链表
void traverse_list(PNODE pHead);
//在链表尾部追加
void append_list(PNODE pHead);
//在指定位置删除节点
void delete_list(PNODE pHead);
//在指定位置插入节点
void insert_list(PNODE pHead);
//修改指定位置节点的值
void change_list(PNODE pHead);
//根据位置查找节点的值
void findByPos_list(PNODE pHead);

int main()
{
    PNODE pHead = NULL;
    //创建链表时不为0,起码有一个有效节点,不然insert就可能出现插入首节点的问题了
    pHead = createList();
    traverse_list(pHead);

//    append_list(pHead);
//    traverse_list(pHead);

//    delete_list(pHead);
//    traverse_list(pHead);

//    insert_list(pHead);
//    traverse_list(pHead);

//    change_list(pHead);
//    traverse_list(pHead);

    findByPos_list(pHead);

    return 0;
}

//创建链表
PNODE createList()
{
    int len;    //有效节点的个数
    int val;    //存放临时数据

    PNODE pHead = (PNODE)malloc(sizeof(Node));
    if(NULL == pHead)
    {
        printf("malloc failed \n");
        exit(-1);
    }
    PNODE pTail = pHead;    //因为还没有新的节点,这时候尾指针和头指针指向同一个内存
    pTail->pNext = NULL;

    printf("The len you need is: ");
    scanf("%d", &len);

    //对链表进行初始化,为所创建的len长度的链表分配内存并赋值
    for(int i=0; i<len; i++)
    {
        //printf里面的%d都是为逗号,后面的值服务的,在输出的时候%d就会替换为逗号后面的值,这里是逗号后面的值给前面的%d
        printf("Please enter no.%d segment val: ", i+1);
        //scanf这里是输出,是%d的值给后面的val,和printf的方向相反,这里把输入的值传递给变量val
        scanf("%d", &val);

        //为新节点分配空间
        PNODE pNew  = (PNODE)malloc(sizeof(NODE));
        {
            if(NULL == pNew)
            {
                printf("failed \n");
                exit(-1);
            }
        }
        pNew->data = val;

        pTail->pNext = pNew;
        pNew->pNext = NULL;
        pTail = pNew;

    }
    return pHead;
}

//遍历并输出链表内容
void traverse_list(PNODE pHead)
{
    PNODE p = pHead->pNext;
    printf("the value of the whole list now is :");
    while(NULL != p->pNext)
    {
        printf("%d ", p->data);

        p = p->pNext;
    }
    //如果p为尾节点了,就把这最后一个p的数据打印出来然后换行
    printf("%d \n \n", p->data);

    return;
}

//尾部追加
void append_list(PNODE pHead)
{
    int val;
    PNODE p = pHead->pNext;
    while(NULL != p->pNext)
    {
        p = p->pNext;
    }

    //创建一个新的节点
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    if(pNew == NULL)
    {
        printf("append failed \n");
    }
    printf("scanf the data you want to append: ");
    //想要给这个变量传值就要取地址,因为这是一个临时变量而非指针
    scanf("%d", &val);
//    printf("%d", val);

    pNew->data = val;
    //跳出循环时p就指向最后一个节点
    p->pNext = pNew;
    pNew->pNext = NULL;

   return;
}

//删除指定位置(首节点为1)
void delete_list(PNODE pHead)
{
    int pos;
    int i = 1;

    printf("where the  position is  you want to delete? ");
    scanf("%d", &pos);

    PNODE q = pHead;
    PNODE p = q->pNext;
    while(i != pos)
    {
        q = q->pNext;
        p = p->pNext;
        i++;
    }
    if(p->pNext == NULL)
    {
        printf("the val you delete is: %d \n", p->data);
        q->pNext = NULL;
        free(p);
    }
    else
    {
        printf("the val you delete is: %d \n", p->data);
        q->pNext = p->pNext;
        free(p);
    }
    return;
}

//插入完成后插入的节点的下标为pos,即在pos为2插入,插入的节点位于2位,原本在2的节点为第3
void insert_list(PNODE pHead)
{
    int pos;
    int i = 1;
    int val;

    PNODE q = pHead;
    PNODE p = q->pNext;

    printf("where the  position is  you want to insert? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    //当i不等于pos时,这里的i和pos是位置相等的,讲这个判断写在printf和scanf之间是为了能在外界输入pos按下回车后
    //如果超过边界了就立即报错,就不进到输入数值的环节了,这样能进入到输入数值那pos就没问题
    while(i != pos)
    {
        q = q->pNext;
        p = p->pNext;

        //这里是判断是否输入的pos超过了已有数组有效场地的最大值,也就是i
        if(p == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }
        i++;
    }

    printf("what the  val do you want to insert? ");
    scanf("%d", &val);

    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    pNew->data = val;

    //排除了超过边界的pos值输入后,所有的pNew一定都是在pHead和p之间插入的,就算一共有3个元素,pos填3,那pNew就在第三,p指针移到第4
    //如果pos填4,则报警
    q->pNext = pNew;
    pNew->pNext = p;

    return;
}

//修改指定位置的节点的值
void change_list(PNODE pHead)
{
    //q指向首节点(如果首节点不存在则指向NULL)
    PNODE q = pHead->pNext;
    int pos;
    int i = 1;
    int val;

    printf("Which node do you want to modify the value? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    while(i != pos)
    {
        q = q->pNext;

        if(q == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }

        i++;
    }
    printf("What the value do you want to set? ");
    scanf("%d", &val);
    q->data = val;
}

//查找指定位置的节点的值
void findByPos_list(PNODE pHead)
{
    //q指向首节点(如果首节点不存在则指向NULL)
    PNODE q = pHead->pNext;
    int pos;
    int i = 1;

    printf("Which node do you want to query the value? ");
    scanf("%d", &pos);

    if(pos<1)
    {
        printf("Failed! Pos must be greater than 0 \n");
    }

    while(i != pos)
    {
        q = q->pNext;

        if(q == NULL)
        {
            printf("Failed! The pos is out of range,positon should beteween 1~%d \n", i);
            return;
        }

        i++;
    }
    printf("the value at position %d is: %d \n", i,q->data);
}

相关标签: 补充知识

上一篇: 分治法

下一篇: 验证码生成