草庐IT

数据结构——创建一个带头节点的单链表(C语言)

你也上网冲浪吗0819 2023-08-04 原文

写在前面:

最近正在学习数据结构中的单链表,看书(《数据结构(第二版)》,下称课本)的时候理解的挺快的。直到自己敲的时候才发现,笔者看懂的只是书上的类C语言,且个人觉得书上的各个基本操作的实现表现得较为简略,导致自己去实现的时候一塌糊涂。笔者认为最难的是创建单链表后,结点数据在其中的存储以及结点之间逻辑关系的存储。

写此博客,录笔者实现单链表的历程。此篇是第一篇,也是第一步,创建带头结点的单链表,且可输入数据。

:笔者刚上大一,学习c语言没多久,内容比较基础,表达没那么专业到位,更多的是帮助自己记录思路,如有错误,欢迎指正。

实现

思路

📍创建结构体变量

📍定义一个链表

📍创建头结点

📍创建新结点

📍打印链表

具体步骤(文末有具体代码及运行效果)

  • 创建结构体

typedef struct node

{

int data;//数据域

struct node *next;//指针域

}LNode,*LinkList;//命名原因如下(出自课本)

笔者的理解LNode表示结点,个数不限;LinkList表示指向头结点的指针,仅有一个

此时,结构体变量创建完成。

  • 定义一个链表

LNode* list;

定义一个LNode类型的list指针变量,用于在函数之间的传递,以储存单链表的每一次改动。

  • 创建头结点

list=createhead()//创建的头结点赋值给list链表

LNode* createhead()

{

LinkList L;//创建头指针

L=(LinkList)malloc(sizeof(LinkList));//为头结点开辟空间,L作为头指针指向这块空间

L->next=NULL;//空链表的尾指针指向空

return L;//将L返回

}

此时,list为一个有头结点的空链表。

  • 创建新结点

createnode(list);//将list传进去,此时list是个指针,传的是单链表的首地址,在函数内部就可改变它;

void createnode(LinkList L)//此处将形参命名为L,且类型为LinkList,意在提示我们传过来的是指

//向头结点的指针;

{

//开辟新结点

LNode* new=(LNode*)malloc(sizeof(LNode));

//安置new的数据域

int data1;

printf("请输入要放入的值");

scanf("%d",&data1);

new->data=data1;

//安置new的指针域,此处使用前插法(后有解释以及后插法的具体实现)

new->next=L->next;//L的指针域赋值给new,即new指向NULL;

L->next=new;//L指向new

}

//由下图不难看出其关系,

  • 至此,一个可以存储数据及逻辑关系的单链表已创建完成。

*****下面解释一下前插法与后插法的区别

首先要明确一点,每次将单链表传到函数内部,单链表都是从头结点开始访问各个元素的,这取决于单链表的有序存储结构

前插法,每次进去新的结点都是插在头结点后面,成为新的首元结点,而链表的访问又是从头结点开始的,则使用前插法会比较方便。

而后插法,每次都要插在尾结点的后面,成为新的尾结点。这就需要我们每次调用时都找到当前尾结点的所在之处。故需要加入一个函数实现遍历的功能。

后插法版本的createnode:

void createnode(list)

{

LNode* new=(LNode*)malloc(sizeof(LNode));

//安置new的数据域

int data1;

printf("请输入要放入的值");

scanf("%d",&data1);

new->data=data1;

//安置new的指针域,此处使用后插法

LNode *tail;//t用来遍历,tail定位尾指针

tail=search(L);

tail->next=new;

new->next=NULL;

tail=new;

}

由下图不难看出。

LNode* search(LinkList L)

{

LNode *p=L;

while(p->next)

p=p->next;

return p;

}

*以下细微差距,第二种方法会让tail为nullptr,造成非法访问,*

*逻辑上没有太大问题,但是仔细分析是有问题的*

  • 打印链表

即遍历

void print(LinkList L)

{

LNode *p=L->next;//不指向L,因为L的数据域没数据,就不必输出

while(p)

{

printf("%d",p->data);

p=p->next;

}

}

  • 此时,单链表的创建已全部完成,以下是顺序完整的代码(用前插法演示

typedef struct node
{
    struct node* next;
    int data;
}LNode,*LinkList;
#include <stdio.h>
#include <stdlib.h>
LNode* createhead()
{
    LinkList L = (LinkList)malloc(sizeof(LinkList));
    L->next = NULL;
    return L;
}
void createnode(LinkList L)
 {
        LNode* new = (LNode*)malloc(sizeof(LNode));
        int data1;
        printf("请输入要放入的值");
        scanf("%d", &data1);
        new->data = data1;
        new->next = L->next;
        L->next = new;
}
void print(LinkList L)
{
    
        LNode* p = L->next;
        while (p)
        {
            printf("%d\n", p->data);
            p = p->next;
        }
    
}
int main()
{
    LNode* list;
    list = createhead();
    while (1)//此处加入死循环,看看是否已经构建起单链表的逻辑结构了
    {
        createnode(list);
        print(list);
    }
}

此为输出的效果,可见单链表已构建成功。

最难的创建单链表已完成,接下来几篇文章将介绍在学生管理系统下的单链表的按姓名查找、按姓名删除、修改、记录学生人数等功能。

谢谢观看!

有关数据结构——创建一个带头节点的单链表(C语言)的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  7. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  8. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  9. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  10. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

随机推荐