用线性链表存储num个数字,降序排列,删除重复整数

文章介绍了如何使用链表结构,结合插入排序思想,创建一个有序链表并删除重复节点的过程,涉及基本的链表操作如节点创建、插入和删除。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前提到了,线性链表的基本操作,包括创建,删除,插入,销毁灯。

现在,利用这些函数的基础迭代,解决问题:

首先创建一个链表:借鉴插入排序的思想,每次输入数据,然后沿着头节点寻找,对比要输入的数据与每个节点所带的值,插入正确的位置。

1.定义三个指针变量,p比较当前比较的节点,pf每次循环后指向p的前一个节点

2.每次输入整数data,建立一个存储data的节点

3.将data节点插入正确的位置


NODE* Creat_Linklist()
{
    NODE* head,*pnew,*p,*pf;
    int i, num, data;

    head = (NODE*)malloc(sizeof(NODE)); //创建头节点
    if (head == NULL)
    {
        printf("head:creat error\n");
        exit(-1);
    }
    head->next = NULL;  

    printf("input the number of integers:\n");
    scanf("%d", &num);  
    printf("input %d integers:\n", num);
    for (i = 0; i < num; i++)   //循环n次,创建n个节点
    {
        scanf("%d", &data);
        pnew = (NODE*)malloc(sizeof(NODE));
        if (pnew == NULL)
        {
            printf("pnew:creat error\n");
            exit(-1);
        }
        //每次创建新节点时,输入数据,并让指针域NULL,防止野指针
        pnew->data = data;
        pnew->next = NULL;
        
        //寻找新数据节点要插入的位置
        pf = head;
        p = head->next;
        while (p != NULL && p->data > data)
        {
            pf = p;    //每次寻找,pf作为p的前驱节点,便于插入
            p = p->next;
        }
        //插入pnew到pf所指节点后
        pnew->next = p; 
        pf->next = pnew;
    }
    return (head);  //返回头指针
}

删除链表里的重复节点:

每次选取一个节点的data,与其他节点的data作比较,如果相等就删除其他节点

void Delete_Linklist(NODE* head)
{
    NODE* p, * q, * r;
    p = head->next;
    while (p != NULL)   //一直到p到链尾停止
    {
        //删除与p节点相同的值,没有则直接跳过
        for (q = p->next; q != NULL && q->data == p->data;)
        {
            r = q;
            q = q->next;
            free(r);
        }
        //p指向下一个节点,每次重复这个操作,直到结束循环
        p->next = q;
        p = q;
    }
}

其他的操作都是前面提到过的链表的基本操作。

看整体:

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


struct LNode
{
    int data;
    struct LNode* next;
};
typedef struct LNode NODE;

NODE* Creat_Linklist();
void Display_Linklist(NODE* head);
void Free_Linklist(head);
void Delete_Linklist(NODE* head);

int main()
{
    NODE* head;
    head = Creat_Linklist();
    if (head == NULL)
        return -1;
    printf("Created orderd linked list:");
    Display_Linklist(head);

    Delete_Linklist(head);
    printf("After deleting duplicate nodes:");
    Display_Linklist(head);
    Free_Linklist(head);
    return 0;
}

NODE* Creat_Linklist()
{
    NODE* head,*pnew,*p,*pf;
    int i, num, data;

    head = (NODE*)malloc(sizeof(NODE)); //创建头节点
    if (head == NULL)
    {
        printf("head:creat error\n");
        exit(-1);
    }
    head->next = NULL;  

    printf("input the number of integers:\n");
    scanf("%d", &num);  
    printf("input %d integers:\n", num);
    for (i = 0; i < num; i++)   //循环n次,创建n个节点
    {
        scanf("%d", &data);
        pnew = (NODE*)malloc(sizeof(NODE));
        if (pnew == NULL)
        {
            printf("pnew:creat error\n");
            exit(-1);
        }
        //每次创建新节点时,输入数据,并让指针域NULL,防止野指针
        pnew->data = data;
        pnew->next = NULL;
        
        //寻找新数据节点要插入的位置
        pf = head;
        p = head->next;
        while (p != NULL && p->data > data)
        {
            pf = p;    //每次寻找,pf作为p的前驱节点,便于插入
            p = p->next;
        }
        //插入pnew到pf所指节点后
        pnew->next = p; 
        pf->next = pnew;
    }
    return (head);  //返回头指针
}

void Display_Linklist(NODE* head)   //显示每个节点的值
{
    NODE* p;
    for (p = head->next; p != NULL; p = p->next)
        printf("%d ", p->data);
    printf("\n");
}

void Delete_Linklist(NODE* head)
{
    NODE* p, * q, * r;
    p = head->next;
    while (p != NULL)   //一直到p到链尾停止
    {
        //删除与p节点相同的值,没有则直接跳过
        for (q = p->next; q != NULL && q->data == p->data;)
        {
            r = q;
            q = q->next;
            free(r);
        }
        //p指向下一个节点,每次重复这个操作,直到结束循环
        p->next = q;
        p = q;
    }
}

void Free_Linklist(NODE* head)    //释放空间
{
    NODE* p,*q;
    p = head;
    while (p->next != NULL)
    {
        q = p->next;
        p->next = q->next;
        free(q);
    }
    free(head);
}

运行结果:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清欢.598

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

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

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

打赏作者

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

抵扣说明:

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

余额充值