数据结构 实验二 单链表的基本操作 ① 逆序建立单链表② 遍历单链表(输出单链表每个元素的值)③ 在单链表第5个元素前插入一个值为999的元素.④ 删除单链表第5个元素._①逆序建立单链表 ②遍历单链表(输出单链表每个元素的值) ③在单链表第5个元素前-程序员宅基地

技术标签: 算法  链表  数据结构  

实验二  单链表的基本操作必做,设计性实验)

  1. 实验目的

了解线性表的链式存储结构和顺序存取特性,熟练掌握线性表的链式存储结构的C语言描述方法,熟练掌握动态链表的基本操作查找、插入、定位等,能在实际应用中选择适当的链表结构。掌握用链表表示特定形式的数据的方法,并能编写出有关运算的算法。

  1. 实验内容

  1. 已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。
  2. 完成单链表上的如下操作:

① 逆序建立单链表

② 遍历单链表(输出单链表每个元素的值)

③ 在单链表第5个元素前插入一个值为999的元素.

④ 删除单链表第5个元素.

  1. 问题描述

    (说明你选做的题目及要求

1、已知线性表中的元素以值递增有序排列,并以单链表作存储结构。试写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删结点空间,并分析你的算法的时间复杂度(注意:mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。

2、完成单链表上的如下操作:

① 逆序建立单链表

② 遍历单链表(输出单链表每个元素的值)

③ 在单链表第5个元素前插入一个值为999的元素.

④ 删除单链表第5个元素.

  1. 数据结构定义

    (说明你算法中用到的数据结构、数据类型的定义

数据结构:线性表的链式存储

在单链表中,假定每个结点类型用Linklist表示,它包括存储元素的数据域,用data表示,其类型用通用类型标识符ElemType 表示,还包括存储后续元素位置的指针域 用next表示。

LinkList类型的定义如下:

Typedef struct LNode

{      ElemType data;

       Struct LNode *next;

}LinkList;

  1. 算法思想及算法设计

    (先文字说明算法的思想,然后给出类C语言算法

1、

尾插法建表:

从一个空表开始,读取字符数组a中的字符,生成新结点,将读取的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头上,直到结束为止

void CreateList(LinkList &L, int n)

{

 L = new LNode; L->next = NULL;

 LNode *r;

 r = L;

 for (int i = 0; i < n; i++)

 {

  printf("请输入链表第%d个元素的值:", i + 1);

  LNode *s;

  s = new LNode;

  scanf("%d", &s->data);

s->next = NULL;r->next = s;r = s;

 }

删除算法:

先将第一个结点的数据跟mink比较,如果小于mink,则指向下一个结点,如果大于mink,跳出,如果小于则将在有效范围内的数据删除并释放结点空间,将删除后的前后两段重新链接。

void DeleteSome(LinkList &L, ElemType mink, ElemType maxk)

{   LinkList p,q,w;

   p=L->next;

   w=NULL;

   while(p->data<=mink)

    {w=p;

    p=p->next;

    if(!p) break; }

   while(p->data>maxk

   {q=p;p=q->next;

    free(q);

    if(!p) break;

    }

    w->next=p; }

2、逆序创建单链表

int transCreat(LinkList head){

 LinkList pnew;

 pnew = (LinkList)malloc(LEN);

 printf("请依次输入数据(输入-1认为输入终止)\n");

 scanf("%d",&pnew->data);

 while(pnew->data!=-1){//先把后边的串上再串前边的

  head->data++;

  pnew->next = head->next;//核心语句

  head->next = pnew;      //核心语句

  pnew = (LinkList)malloc(LEN);

  scanf("%d",&pnew->data);

 }
  1. 插入节点的运算

先在链表中确定头结点p,将要插入的值赋值给新结点的数据域,将插入位置之后的元素都向后移一位,将新结点插入。

int insertLNode(LinkList head,int num,int locate){

 LinkList pnew,p;

 int i=0;

 p = head;//p指向第0个结点 i也表示第0个结点

 pnew = (LinkList)malloc(LEN);

 pnew->data = num;

 while(p&&i<locate-1){//p的位置停在所要插入位置的前一位

  p = p->next;

  i++;//p往后移动 i作为一个位置游标就加1

 }

 pnew->next = p->next;

 p->next = pnew;

 head->data++;

 return OK;

}

  1. 实验代码

    (即C语言程序

实验一

#include<stdio.h>

#include<iostream>

using namespace std;

typedef struct LNode

{

 int data;

 struct LNode *next;

}LNode, *LinkList;


int InitList(LinkList &L)

{

 L = new LNode;

 L->next = NULL;

 return 1;

}


void TraveList(LinkList L)

{

 LNode *p;

 p = L->next;



 while (p)

 {

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

  p = p->next;

 }

 printf("\n");

}


// 尾插法建立链表

void CreateList(LinkList &L, int n)

{

 L = new LNode;

 L->next = NULL;

 LNode *r;

 r = L;

 for (int i = 0; i < n; i++)

 {

  printf("请输入链表第%d个元素的值:", i + 1);

  LNode *s;

  s = new LNode;

  scanf("%d", &s->data);

  s->next = NULL;

  r->next = s;

  r = s;

 }

}


void Delete(LinkList &L, int mink, int maxk)

{   LinkList p,q,w;

   p=L->next;

   w=NULL;

   while(p->data<=mink) //先将第一个结点的数据跟mink比较,

    {w=p;

    p=p->next;          //如果小于mink,则指向下一个结点

    if(!p) break;        //如果大于mink,跳出

    }

  
   while(p->data

   {q=p;                 //如果大于,则跳出

    p=q->next;           //如果小于则将在有效范围内的数据删除并释放结点空间

    free(q);

    if(!p) break;

    }

    w->next=p;          //将删除后的前后两段重新链接

}

int main()

{

 LinkList L1;

 if (InitList(L1))

 {

  printf("L1初始化成功!\n");

 }

 else

 {

  printf("L1初始化失败!\n");

 }

 printf("请输入L1的长度:");

 int n1;

 scanf("%d", &n1);

 CreateList(L1, n1);

 TraveList(L1);


 int a, b;

 printf("请输入min和max的值\n");

 scanf("%d %d",&a,&b);

 printf("删除链表中大于%d小于%d的节点:\n", a, b);

 Delete(L1, a, b);

 TraveList(L1);

 system("pause");

 return 0;

}

实验二

#include<stdio.h>

#include<stdlib.h>

#define OK 1

#define ERROR 0

#define LEN sizeof(struct LNode)

struct LNode{

 int data;

 struct LNode *next;

};

typedef struct LNode LNode,* LinkList;



//初始化

LinkList InitLNode(void){

 LinkList head = (LinkList)malloc(LEN);

 if(!head){

  printf("存储空间分配失败!\n");

  exit(ERROR);

 }

 head->data = 0;

 head->next = NULL;

 return head;

}

//逆序创建单链表

int transCreat(LinkList head){

 LinkList pnew;

 pnew = (LinkList)malloc(LEN);

 printf("请依次输入数据(输入-1认为输入终止)\n");

 scanf("%d",&pnew->data);

 while(pnew->data!=-1){//先把后边的串上再串前边的

  head->data++;

  pnew->next = head->next;//核心语句

  head->next = pnew;      //核心语句

  pnew = (LinkList)malloc(LEN);

  scanf("%d",&pnew->data);

 }

 free(pnew);//此时的pnew数据域里存放着-1 没有被链入到链表中 无用

 return OK;

}

//输出单链表

int printLNode(LinkList head){

 if(!head->next){

  printf("空链表!\n");

  return ERROR;

 }

 LinkList p;

 p = head->next;

 do{

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

  p = p->next ;

 }while(p);

}

//插入

int insertLNode(LinkList head,int num,int locate){

 if(locate<1||locate>head->data+1){

  printf("插入位置有误!\n");

  exit(ERROR);

 }

 LinkList pnew,p;

 int i=0;

 p = head;//p指向第0个结点 i也表示第0个结点

 pnew = (LinkList)malloc(LEN);

 pnew->data = num;

 while(p&&i<locate-1){//p的位置停在所要插入位置的前一位

  p = p->next;

  i++;//p往后移动 i作为一个位置游标就加1

 }

 pnew->next = p->next;

 p->next = pnew;

 head->data++;

 return OK;

}

//删除

int delLinkList(LinkList head,int locate){

 if(!head->next){

  printf("空链表!\n");

  exit(ERROR);

 }

 if(locate<1||locate>head->data){

  printf("位置有误!\n");

  return ERROR;

 }

 LinkList pleft,pright;

 int i = 0;

 pleft = pright = head;

 while(pright&&i<locate){

  pleft = pright;

  pright = pright->next;

  i++;//pright和i指的是同一个结点

 }

 pleft->next = pright->next;

 head->data--;

 free(pright);

 return OK;

}



main(){

 LinkList head;

 head = InitLNode();

 transCreat(head);

 printLNode(head);

 printf("\n\n在单链表第5个元素前插入一个值为999的元素后结果是:\n");

 insertLNode(head,999,5);

 printLNode(head);

 printf("\n\n删除单链表第5个元素后结果是:\n");

 delLinkList(head,5);

 printLNode(head);

}
  1. 算法测试结果

    (说明测试数据,粘贴实验结果图

(1)链表元素{ 1 2 3 4 5 } mink和maxk分别是1,3

 

(2)链表元素{1 2 3 4 5 6 7 8 9 10}

 

  1. 分析与总结

    (1)算法复杂度分析及优、缺点分析

        (说明你编写算法的复杂度,算法的优点和缺点有哪些

尾插法建表void CreateList(LinkList &L, int n)的时间复杂度为O(n),删除插入while循环体中的语句频率和元素位置有关,因此算法时间复杂度为O(n).已知链表中元素插入删除位置的情况下,在单链表中插入或删除一个结点时,仅需要修改指针而不需要移动元素。

    (2)实验总结

        (说明你怎么解决实验中遇到的问题,有什么收获

通过这次实验,更好的了解和学习到了单链表中链表建立,元素删除,插入等基本操作,熟悉了操作平台的使用,对单链表的操作有更好的认识。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_51308557/article/details/121954423

智能推荐

python 新闻摘要_每日新闻摘要:运营商承诺他们不再出售您的位置…-程序员宅基地

文章浏览阅读174次。python 新闻摘要Last year it was discovered that Verizon, Sprint, AT&T, and T-Mobile were all selling your real-time location data to third-party companies. They offered no oversight of what the compan...

【调剂】辽宁科技大学材料与冶金学院夏垒招收材料、金属加工、化学及相关学科调剂考生...-程序员宅基地

文章浏览阅读162次。公众号【计算机与软件考研】每天都会发布最新的计算机考研调剂信息!点击公众号界面左下角的调剂信息或者公众号回复“调剂”是计算机/软件等专业的所有调剂信息集合,会一直更新的。夏垒,博士,2020年入选辽宁省“百千万人才工程”,担任《轧钢》、《特殊钢》、《机械工程导报》等期刊首届青年编委,中国机械工程学会高级会员,中国材料研究学会会员,中国化学会会员。长期致力于金属加工摩擦、磨损与工艺润滑;材料腐蚀与防..._辽宁省自然科学学术成果 鞍钢

PyCharm更换pip源为国内源、模块安装、PyCharm依赖包导入导出教程_pycharm换源-程序员宅基地

文章浏览阅读2.9w次,点赞10次,收藏93次。PyCharm更换为国内pip源后,下载速度超级快!_pycharm换源

elasticsearch+logstash+kibana+kafka日志分析系统的安装和配置(一:安装篇)_elasticsearch(7.13.3) + logstash(7.13.3) + kibana(-程序员宅基地

文章浏览阅读252次。安装jdkyum install -y java-1.8.0-openjdk.x86_64 yum安装ElasticSearchCreate a file called elasticsearch.repo in the /etc/yum.repos.d/[elasticsearch]name=Elasticsearch repository for 7.x packagesbaseurl=https://artifacts.elastic.co/packages/7.x/yumgpgche_elasticsearch(7.13.3) + logstash(7.13.3) + kibana(7.13.3) + kafka

tf.global_variables_initializer()使用-程序员宅基地

文章浏览阅读5.3k次,点赞4次,收藏12次。# 必须要使用global_variables_initializer的场合# 含有tf.Variable的环境下,因为tf中建立的变量是没有初始化的,也就是在debug时还不是一个tensor量,而是一个Variable变量类型size_out = 10tensor = tf.Variable(tf.random_normal(shape=[size_out]))init = tf.global_variables_initializer()with tf.Session() as sess:_tf.global_variables_initializer()

基音周期估计-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏13次。这是语音信号的数字处理课程的课程作业,这里采用了自相关法对基音周期进行估计。语料采样率:8kHz;量化精度为16bits/sample;1、 算法描述本次实验选择了自相关方法对基音周期进行估计。算法主要包括以下几个步骤预处理:包括语料读取和分帧、滤波。阈值设定:对每帧数据选择合适的阈值进行设定削波处理:提高检测准确性互相关求基音频率:通过求解互(自)相..._基音周期估计基本流程

随便推点

SSH修改登录端口并配置免密登录(非root)_ssh ip默认为非root如何调-程序员宅基地

文章浏览阅读2.4k次。实验环境本地 MacOS 10.14.4远程服务器CentOS 7.5 64位Firewalld本地命令前缀 [admin@MacBookPro]$服务器命令前缀 [A@CentOS]$​ 最近在建站后,发现不到2天我的小破站就有600次ssh远程登录的尝试。心中不免一阵寒意,为了解决这个问题特地读取了ssh官方的文档,对网站的ssh登录进行了一些措施。​ 首先要了解 SSH免密登录的原理,免密登录需要使用 ssh 的非对称加密方式,登录无需密码,但是需要携带秘钥。本地若想登录._ssh ip默认为非root如何调

oracle电子书百度云盘,ypzdnoracle-e7-bb-8f-e5-85-b8-e6-95-99-e7-a8-8b.pdf-程序员宅基地

文章浏览阅读323次。ypzdnoracle-e7-bb-8f-e5-85-b8-e6-95-99-e7-a8-8b.pdf-e6-98-af-e7-99-be-e5-ba-a6-e7-bd-91-e7-9b-98-e5-ad-98-e5-82-a8-e5-86-85-e5-ae-b9-3cbr-2f-3eoracle-e7-bb-8f-e5-85-b8-e6-95-99-e7-a8-8b.pdf-e7-9a-84-e..._%e5%9b%bd%e7%8e%8b%e6%b8%b8%e6%88%8f%e5%a6%88%e5%a6%88

Cheering Gym-101522C_cheering lsc pcms-程序员宅基地

文章浏览阅读145次。Cheering Gym-101522C_cheering lsc pcms

Domain agnostic feature learning-程序员宅基地

文章浏览阅读821次。Paper-infotitle :Domain Agnostic Feature Learning forImage and Video Based Face Anti-spoofing[2019-arXiv] author:Suman Saha,Wenhao Xu,Menelaos Kanakis,Stamatios Georgoulis, et al. insight ..._agnostic feature

快速入门Jdbc原理+Jdbc实战-程序员宅基地

文章浏览阅读664次。Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。

【数据结构】Splay树 + 文艺平衡树-程序员宅基地

文章浏览阅读1k次,点赞38次,收藏8次。就是一个长这样的树,树中每个结点都有一个父结点(除了根结点没有父结点)和最多两个子结点,每个结点的左儿子一定比它小,右儿子一定比它大。这棵树的先序遍历很容易知道就是:1 2 3 4 5 6 7 (根左右)我们还可以从另一个角度理解先序遍历:把整棵树映射到 x 轴上,也就是把它压扁也就是这样:先序遍历从左到右读出来就可以了。