C语言链表的增删查改

小经验:在VS2017中,使用while(scanf(“%d”,&i)!= NULL){......}时,结束输入需要输入三次ctrl+z+空格

func.h

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

typedef struct student {
    int number;
    struct student* pnext;
}stu, *pstu; 

void list_print(pstu);//打印
void list_head_insert(pstu*,pstu*,int);//头插法
void list_tail_insert(pstu*, pstu*, int);//尾插法
void list_sort_insert(pstu*, pstu*, int);//有序插入
void list_delete(pstu*, pstu*, int);//节点删除

func.c

#include "func.h"

void list_head_insert(pstu* pphead, pstu* pptail, int i)
{//头插法
    pstu pnew;
    pnew = (pstu)malloc(sizeof(stu));//申请空间
    memset(pnew,0,sizeof(stu));//初始化

    pnew->number = i;

    if (*pphead == NULL) {//链表为空,新节点既是头指针,又是尾指针
        *pphead = pnew;
        *pptail = pnew;
    }
    else {
        pnew->pnext = *pphead;//原有的链表头作为新节点的pnext
        *pphead = pnew;//新节点作为节点头
    }
}

void list_tail_insert(pstu* pphead, pstu* pptail, int i)
{//尾插法实现
    pstu pnew;
    pnew = (pstu)calloc(1, sizeof(stu));//calloc会进行空间初始化
    pnew->number = i;
    if (*pptail == NULL) {
        *pphead = pnew;
        *pptail = pnew;
    }
    else
    {
        (*pptail)->pnext = pnew;//新节点变成原有尾节点的pnext
        *pptail = pnew;//新节点变成尾节点
    }
}

void list_sort_insert(pstu* pphead, pstu* pptail, int i)
{//有序插入实现
    pstu pcur,ppre;//游标
    pcur = *pphead;
    ppre = *pphead;

    pstu pnew;
    pnew = (pstu)calloc(1, sizeof(stu));//calloc会进行空间初始化
    pnew->number = i;

    if (*pptail == NULL) {//链表为空
        *pphead = pnew;
        *pptail = pnew;
    }
    else if (i<(*pphead)->number)//小于头结点,类似头插法
    {
        pnew->pnext = *pphead;//原有的链表头作为新节点的pnext
        *pphead = pnew;//新节点作为节点头
    }else
    {
        while (pcur!=NULL)
        {//插入中间
            if (i<pcur->number)
            {
                ppre->pnext = pnew;
                pnew->pnext = pcur;
                break;
            }
            ppre = pcur;
            pcur = pcur->pnext;
        }
        if (pcur == NULL)
        {//pcur为null,说明插入尾节点
            (*pptail)->pnext = pnew;
            *pptail = pnew;
        }
    }
}

void list_delete(pstu* pphead, pstu* pptail, int d)
{//删除实现
    pstu ppre = *pphead, pcur = *pphead;
    if (*pphead == NULL) //链表为空
    {
        printf("List is empty\n");
        return;
    }else if(pcur->number==d)//头结点删除
    {
        *pphead = pcur->pnext;
        if (*pphead == NULL) {//删除节点后,链表为空
            *pptail = NULL;
        }
        free(pcur);
    }else//删除中间和尾部
    {
        while (pcur != NULL)
        {
            if (pcur->number == d)
            {
                ppre->pnext = pcur->pnext;
                break;
            }
            ppre = pcur;
            pcur = pcur->pnext;
        }
        if (pcur==*pptail) //删除的是尾节点
        {
            *pptail = ppre;
        }
        if (pcur == NULL) //未找到节点
        {
            printf("This node is not in list\n");
        }
        else
        {
            free(pcur);
        }
    }
}

void list_print(pstu phead) {
    while (phead != NULL)
    {
        printf("%3d", phead->number);
        phead = phead->pnext;
    }
    printf("\n");
}

main.c

#include "func.h"

int main() {
    pstu phead = NULL;
    pstu ptail = NULL;
    int i;
     while(scanf("%d",&i)!=EOF)
    {
        //list_head_insert(&phead, &ptail,i);//头插法
        //list_tail_insert(&phead, &ptail, i);//尾插法
        list_sort_insert(&phead, &ptail, i);//有序插入
    }
    list_print(phead);
    while (scanf("%d", &i) != EOF) {
        list_delete(&phead, &ptail, i);
        list_print(phead);
    }
    system("pause");
}

原文地址:https://www.cnblogs.com/cicy/p/10755418.html

时间: 2024-10-20 07:50:18

C语言链表的增删查改的相关文章

单链表的增删查改等基本操作C++实现

单链表的初始化.增删查改.遍历一次找中间结点.删除一个无头单链表的非尾结点(不给头结点) #include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef int DataType; typedef struct ListNode { struct ListNode* _next; DataType _data; }ListNode; void InitList(ListNode* &pHead) {

单向链表的增删查改

链表(Linked List) 链表是有序的列表 链表是以节点的方式来存储,是链式存储 每个节点包含data域,next域:指向下一个节点 链表的各个节点不一定是连续存储 链表分带头节点的链表和没有头节点的链表,根据实际需求来确定 单链表的增删改查 package linkedlist; import javax.swing.plaf.synth.SynthSeparatorUI; public class SingleLinkedListDemo { public static void ma

c++单链表【构造函数、运算符重载、析构函数、增删查改等】

c++中的单向链表写法:实现增删查改.构造函数.运算符重载.析构函数等. 建立头文件SList.h #pragma once typedef int DataType; //SList要访问SListNode,可以通过友元函数实现,友元函数在被访问的类中 class SListNode { friend class SList;//友元函数 public: SListNode(const DataType x) :_data(x) , _next(NULL) {} private: SListN

c++双链表【构造函数、运算符重载、析构函数、增删查改及逆置等】

c++中的双向链表写法,主要实现(增删查改,链表逆置,构造函数,运算符重载,等) 建立头文件SList.h #pragma once typedef int DataType; class ListNode { friend class List;//友元函数 public: ListNode(const DataType x) :_data(x) , _prev(NULL) , _next(NULL) {} private: DataType _data; ListNode* _prev; L

c++中的顺序表写法,主要实现(增删查改,构造函数,运算符重载)

本文的内容主要是,利用c++写出顺序表,并对写出的代码进行测试, 主要实现的功能:实现对顺序表的增删查改, 要写的函数:构造函数,赋值运算符重载,析构函数.在编写代码过程中应注意到深浅拷贝问题. 下面是顺序表的类函数: #pragma once #include<iostream> using namespace std; typedef int DataType; class SeqList { public: SeqList(); SeqList(DataType *array, size

6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

8天学通MongoDB——第二天 细说增删查改

看过上一篇,相信大家都会知道如何开启mongodb了,这篇就细说下其中的增删查改,首先当我们用上一篇同样的方式打开mongodb,突然 傻眼了,擦,竟然开启不了,仔细观察“划线区域“的信息,发现db文件夹下有一个类似的”lock file”阻止了mongodb的开启,接下来我们要做的就 是干掉它,之后,开启成功,关于mongodb的管理方式将在后续文章分享. 一: Insert操作 上一篇也说过,文档是采用“K-V”格式存储的,如果大家对JSON比较熟悉的话,我相信学mongodb是手到擒来,我

Mongodb学习总结-2(细说增删查改)

看过上一篇,相信大家都会知道如何开启mongodb了,这篇就细说下其中的增删查改,首先当我们用上一篇同样的方式打开mongodb,突然 傻眼了,擦,竟然开启不了,仔细观察“划线区域“的信息,发现db文件夹下有一个类似的”lock file”阻止了mongodb的开启,接下来我们要做的就 是干掉它,之后,开启成功,关于mongodb的管理方式将在后续文章分享. 一: Insert操作 上一篇也说过,文档是采用“K-V”格式存储的,如果大家对JSON比较熟悉的话,我相信学mongodb是手到擒来,我

golang使用json格式实现增删查改

需求和思路 在一般的小项目或者一个小软件,例如客户端之类的小程序中,可能会需要数据的持久化.但是使用一般的数据库(Mysql)之类的不合适.使用sqlite3这种嵌入式的是个较好的方法,但是Go语言中sqlite3的库是C语言的,Cgo不支持跨平台编译.正是由于这种需求,才想到使用json格式将数据直接保存在文件中. 具体的思路是怎么样呢? 在Go语言中如果要将数据转化成json格式的话,有两种格式 struct 和 map. 如果同时需要增删查改功能的话,将map作为中间格式是比较合适的.接下