严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现)

2023-12-04 08:52

本文主要是介绍严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

本题代码如下

void deletemidst(linklist* L, int mink, int maxk)
{lnode* p = (*L)->next, * pre = *L; // 定义指针p和pre分别指向链表头结点的下一个结点和链表头结点lnode* q; // 定义指针q用于释放临时结点while (p) // 遍历链表{if (p->data > mink && p->data < maxk) // 如果当前结点的值在指定范围内{q = p; // 将当前结点赋值给临时结点qp = p->next; // 将指针p指向下一个结点pre->next = p; // 将指针pre的next指针指向下一个结点free(q); // 释放临时结点q所占用的内存空间}else // 如果当前结点的值不在指定范围内{p = p->next; // 将指针p指向下一个结点pre = pre->next; // 将指针pre指向下一个结点}}
}

完整测试代码如下

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{int data; // 数据域,存储整数值struct lnode* next; // 指针域,指向下一个节点
}lnode, * linklist; // 定义链表结构体和指针类型
int a[8] = { 1,2,3,4,5,6,7,8 }; // 初始化数组a
int n = 8; // 数组a的长度
// 构建链表函数
void buildlinklist(linklist* L)
{*L = (lnode*)malloc(sizeof(lnode)); // 分配内存空间给链表头结点(*L)->next = NULL; // 初始化链表头结点的next指针为NULLlnode* s, * r = *L; // 定义临时结点s和当前结点rint i = 0;for (i = 0; i < n; i++) // 遍历数组a{s = (lnode*)malloc(sizeof(lnode)); // 分配内存空间给临时结点ss->data = a[i]; // 将数组a中的元素赋值给临时结点s的data域s->next = r->next; // 将当前结点的next指针指向临时结点的next指针所指向的结点r->next = s; // 将当前结点的next指针指向临时结点sr = s; // 更新当前结点r为临时结点s}r->next = NULL; // 将最后一个结点的next指针设为NULL
}
// 删除指定范围内的值函数
void deletemidst(linklist* L, int mink, int maxk)
{lnode* p = (*L)->next, * pre = *L; // 定义指针p和pre分别指向链表头结点的下一个结点和链表头结点lnode* q; // 定义指针q用于释放临时结点while (p) // 遍历链表{if (p->data > mink && p->data < maxk) // 如果当前结点的值在指定范围内{q = p; // 将当前结点赋值给临时结点qp = p->next; // 将指针p指向下一个结点pre->next = p; // 将指针pre的next指针指向下一个结点free(q); // 释放临时结点q所占用的内存空间}else // 如果当前结点的值不在指定范围内{p = p->next; // 将指针p指向下一个结点pre = pre->next; // 将指针pre指向下一个结点}}
}
// 打印链表函数
void print(linklist* L)
{lnode* k = (*L)->next; // 定义指针k指向链表头结点的下一个结点while (k) // 遍历链表{printf("%d ", k->data); // 输出当前结点的值k = k->next; // 将指针k指向下一个结点}
}int main()
{linklist L; // 定义链表Lbuildlinklist(&L); // 调用构建链表函数printf("原始单链表为:"); // 输出提示信息print(&L); // 调用打印链表函数printf("删除mink与maxk中间的值后的单链表为:"); // 输出提示信息deletemidst(&L, 2, 6); // 调用删除指定范围内的值函数print(&L); // 调用打印链表函数return 0; // 返回0表示程序正常结束
}

测试结果为

 

2.20 同 2.19 题条件,试写一高效的算法,删除表中所有值相同的多余元素(得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法的时间复杂度。

本题代码如下

void deleterepeat(linklist* L)
{lnode* p = (*L)->next, * pre = *L;//p为工作指针,pre为它的前驱指针防止断链lnode* q;while (p->next!=NULL){if (p->next->data == pre->next->data)//如果p的后继的值域等与它本身则执行删除操作{q = p;p = p->next;pre->next = p;free(q);}else//否则继续向后遍历{p = p->next;pre = pre->next;}}
}void deleterepeat(linklist* L)
{lnode* p = (*L)->next, * pre = *L;//p为工作指针,pre为它的前驱指针防止断链lnode* q;while (p->next!=NULL){if (p->next->data == pre->next->data)//如果p的后继的值域等与它本身则执行删除操作{q = p;p = p->next;pre->next = p;free(q);}else//否则继续向后遍历{p = p->next;pre = pre->next;}}
}

完整测试代码

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{int data;struct lnode* next;
}lnode,*linklist;
int a[8] = { 1,2,2,3,3,4,5,6 };
int n = 8;
void buildlinklist(linklist* L)
{*L = (lnode*)malloc(sizeof(lnode));(*L)->next = NULL;int i = 0;lnode* s, * r = *L;for (i = 0; i < n; i++){s = (lnode*)malloc(sizeof(lnode));s->data = a[i];s->next = r->next;r->next = s;r = s;}r->next = NULL;
}
void deleterepeat(linklist* L)
{lnode* p = (*L)->next, * pre = *L;//p为工作指针,pre为它的前驱指针防止断链lnode* q;while (p->next!=NULL){if (p->next->data == pre->next->data)//如果p的后继的值域等与它本身则执行删除操作{q = p;p = p->next;pre->next = p;free(q);}else//否则继续向后遍历{p = p->next;pre = pre->next;}}
}
void print(linklist* L)
{lnode* k = (*L)->next;while (k){printf("%d ", k->data);k = k->next;}
}
int main()
{linklist L;buildlinklist(&L);printf("原始单链表为:"); print(&L); // 调用打印链表函数printf("\n删除重复值后的单链表为:");deleterepeat(&L); // 调用删除重复值的函数print(&L); // 调用打印链表函数return 0; // 返回0表示程序正常结束
}

测试结果为

 

2.21 试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表(a1,a2,...,an)逆置为(an,...,a2,a1)。可以看下面这个(说的不好请见谅)👇

c语言代码实现数据结构课后代码题顺序表p18 2_哔哩哔哩_bilibili

本题代码如下

void nizhi(struct sqlist *s)
{int i = 0; // 定义一个整型变量i,用于遍历顺序表int j = s->length; // 定义一个整型变量j,用于存储顺序表的长度int temp = 0; // 定义一个整型变量temp,用于临时存储元素for (i = 0; i < s->length / 2; i++) // 遍历顺序表的前半部分{temp = s->a[i]; // 将当前元素存储到temp中s->a[i] = s->a[s->length - 1 - i]; // 将后半部分的元素赋值给前半部分s->a[s->length - 1 - i] = temp; // 将temp中的元素赋值给后半部分}
}

完整测试代码如下

#include<stdio.h>
#define Max 10
struct sqlist
{int a[Max];int length;
};
void nizhi(struct sqlist *s)
{int i = 0; // 定义一个整型变量i,用于遍历顺序表int j = s->length; // 定义一个整型变量j,用于存储顺序表的长度int temp = 0; // 定义一个整型变量temp,用于临时存储元素for (i = 0; i < s->length / 2; i++) // 遍历顺序表的前半部分{temp = s->a[i]; // 将当前元素存储到temp中s->a[i] = s->a[s->length - 1 - i]; // 将后半部分的元素赋值给前半部分s->a[s->length - 1 - i] = temp; // 将temp中的元素赋值给后半部分}
}
int main()
{struct sqlist s; // 定义两个顺序表变量sint i = 0; // 定义一个整型变量,用于遍历顺序表ss.length = 5; // 设置顺序表s的长度为5for (i = 0; i < s.length; i++) // 遍历交集结果scanf("%d", &s.a[i]);printf("原顺序表为:");for (i = 0; i < s.length; i++) // 遍历交集结果printf("%d ", s.a[i]); // 输出交集结果中的每个元素nizhi(&s);printf("\n逆置后的顺序表为:");for (i = 0; i < s.length; i++) // 遍历交集结果printf("%d ", s.a[i]); // 输出交集结果中的每个元素return 0; // 程序正常结束,返回0
}

测试结果为

2.22试写一算法,对单链表实现就地逆置(可以看下面的视频讲解)👇

c语言代码实现数据结构课后代码题顺序表p18 2_哔哩哔哩_bilibili

 本题代码如下

void nizhi(linklist* L)//单链表就地逆置
{lnode* p = (*L)->next;lnode* r = p;(*L)->next = NULL;while (p != NULL){p = p->next;r->next = (*L)->next;(*L)->next = r;r = p;}
}

完整测试代码如下

#include<stdio.h>
#define Max 50
struct sqlist
{int a[Max];int length;
};
void nizhi(struct sqlist* s)
{int temp = 0;for (int i = 0; i < s->length / 2; i++){temp = s->a[i];s->a[i] = s->a[s->length - i - 1];s->a[s->length - 1 - i] = temp;}
}
int main()
{struct sqlist s;int j = 0;s.length = 5;for (j = 0; j < s.length; j++)scanf("%d", &s.a[j]);printf("原先数组为:");for (j = 0; j < s.length; j++)printf("%d", s.a[j]);nizhi(&s);printf("\n逆置后的数组为:");for (j = 0; j < s.length; j++)printf("%d", s.a[j]);return 0;
}

测试结果为 

 

 2.23

本题代码如下

linklist Union(linklist* A, linklist* B)
{lnode *C = (lnode*)malloc(sizeof(lnode));C->next = NULL;lnode* ra = (*A)->next, * rb = (*B)->next;lnode* rc = C;while (ra && rb){if (ra->data<rb->data)//若A中当前结点小于B中当前结点值{rc->next = ra;rc = ra;ra = ra->next;}else if (ra->data>rb->data)//若A中当前结点大于B中当前结点值{rc->next = rb;rc = rb;rb = rb->next;}else{rc->next = ra;rc = ra;ra = ra->next;rb= rb->next;}}while (ra)//B遍历完,A没有遍历完{rc->next= ra;rc = ra;ra = ra->next;}while (rb)//A遍历完,B没有遍历完{rc->next = rb;rc = rb;rb= rb->next;}rc->next = NULL; //结果表的表尾结点置空return C;
}

完整测试代码如下

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{int data;struct lnode* next;
}lnode, * linklist;
int na = 5;
int nb = 3;
int a[5] = { 1,3,5,7,9};
int b[3] = { 2,4,6 };
void buildlinklist(linklist* L, int arr[], int n)//创建链表
{*L = (lnode*)malloc(sizeof(lnode));(*L)->next = NULL;lnode* s = *L, * r = *L;int i = 0;for (i = 0; i < n; i++){s = (lnode*)malloc(sizeof(lnode));s->data = arr[i];s->next = r->next;r->next = s;r = s;}r->next = NULL;
}
linklist Union(linklist* A, linklist* B)
{lnode *C = (lnode*)malloc(sizeof(lnode));C->next = NULL;lnode* ra = (*A)->next, * rb = (*B)->next;lnode* rc = C;while (ra && rb){if (ra->data<rb->data)//若A中当前结点小于B中当前结点值{rc->next = ra;rc = ra;ra = ra->next;}else if (ra->data>rb->data)//若A中当前结点大于B中当前结点值{rc->next = rb;rc = rb;rb = rb->next;}else{rc->next = ra;rc = ra;ra = ra->next;rb= rb->next;}}while (ra)//B遍历完,A没有遍历完{rc->next= ra;rc = ra;ra = ra->next;}while (rb)//A遍历完,B没有遍历完{rc->next = rb;rc = rb;rb= rb->next;}rc->next = NULL; //结果表的表尾结点置空return C;
}
void print(linklist* L)//输出单链表
{lnode* k = (*L)->next;while (k){printf("%d ", k->data);k = k->next;}
}
int main()
{linklist A, B;buildlinklist(&A, a, na);buildlinklist(&B, b, nb);printf("A链表为:");print(&A);printf("\nB链表为:");print(&B);linklist C = Union(&A, &B);printf("\n合并后的链表为:");print(&C);return 0;
}

 测试结果如下

 

 2.24假设有两个按元素值递增有序排列的线性表A和B均以单链表作存储结构,请编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许表中含有值相同的元素)排列的线性表 C,并要求利用原表(即A表和B 表)的结点空间构造C表。

本题代码如下

linklist Union(linklist* A, linklist* B)
{lnode* C = (lnode*)malloc(sizeof(lnode));C->next = NULL;lnode* ra = (*A)->next, * rb = (*B)->next;lnode* rapre = *A, * rbpre = *B;//rapre为ra的前驱指针,rbpre为rb的前去指针 lnode* rc = C;while (ra && rb){if (ra->data < rb->data)//若A中当前结点小于B中当前结点值{rapre = ra->next;ra->next=rc->next ;rc->next= ra;ra =rapre;}else if (ra->data > rb->data)//若A中当前结点大于B中当前结点值{rbpre = rb->next;rb->next = rc->next;rc->next = rb;rb = rbpre;}else{rapre = ra->next;ra->next = rc->next;rc->next = ra;ra = rapre;rb = rb->next;}}while (ra)//B遍历完,A没有遍历完{rapre = ra->next;ra->next = rc->next;rc->next = ra;ra = rapre;}while (rb)//A遍历完,B没有遍历完{rbpre = rb->next;rb->next = rc->next;rc->next = rb;rb = rbpre;}return C;
}

完整测试代码如下

#include<stdio.h>
#include<stdlib.h>
typedef struct lnode
{int data;struct lnode* next;
}lnode, * linklist;
int na = 5;
int nb = 8;
int a[5] = { 1,3,5,7,9 };
int b[8] = { 2,4,6,8,10,12,14,16 };
void buildlinklist(linklist* L, int arr[], int n)//创建链表
{*L = (lnode*)malloc(sizeof(lnode));(*L)->next = NULL;lnode* s = *L, * r = *L;int i = 0;for (i = 0; i < n; i++){s = (lnode*)malloc(sizeof(lnode));s->data = arr[i];s->next = r->next;r->next = s;r = s;}r->next = NULL;
}
linklist Union(linklist* A, linklist* B)
{lnode* C = (lnode*)malloc(sizeof(lnode));C->next = NULL;lnode* ra = (*A)->next, * rb = (*B)->next;lnode* rapre = *A, * rbpre = *B;//rapre为ra的前驱指针,rbpre为rb的前去指针 lnode* rc = C;while (ra && rb){if (ra->data < rb->data)//若A中当前结点小于B中当前结点值{rapre = ra->next;ra->next=rc->next ;rc->next= ra;ra =rapre;}else if (ra->data > rb->data)//若A中当前结点大于B中当前结点值{rbpre = rb->next;rb->next = rc->next;rc->next = rb;rb = rbpre;}else{rapre = ra->next;ra->next = rc->next;rc->next = ra;ra = rapre;rb = rb->next;}}while (ra)//B遍历完,A没有遍历完{rapre = ra->next;ra->next = rc->next;rc->next = ra;ra = rapre;}while (rb)//A遍历完,B没有遍历完{rbpre = rb->next;rb->next = rc->next;rc->next = rb;rb = rbpre;}return C;
}
void print(linklist* L)//输出单链表
{lnode* k = (*L)->next;while (k){printf("%d ", k->data);k = k->next;}
}
int main()
{linklist A, B;buildlinklist(&A, a, na);buildlinklist(&B, b, nb);printf("A链表为:");print(&A);printf("\nB链表为:");print(&B);linklist C = Union(&A, &B);printf("\n合并后的链表为:");print(&C);return 0;
}

测试结果如下

 

这篇关于严蔚敏数据结构p17(2.19)——p18(2.24) (c语言代码实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/452861

相关文章

C#提取PDF表单数据的实现流程

《C#提取PDF表单数据的实现流程》PDF表单是一种常见的数据收集工具,广泛应用于调查问卷、业务合同等场景,凭借出色的跨平台兼容性和标准化特点,PDF表单在各行各业中得到了广泛应用,本文将探讨如何使用... 目录引言使用工具C# 提取多个PDF表单域的数据C# 提取特定PDF表单域的数据引言PDF表单是一

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

PyCharm接入DeepSeek实现AI编程的操作流程

《PyCharm接入DeepSeek实现AI编程的操作流程》DeepSeek是一家专注于人工智能技术研发的公司,致力于开发高性能、低成本的AI模型,接下来,我们把DeepSeek接入到PyCharm中... 目录引言效果演示创建API key在PyCharm中下载Continue插件配置Continue引言

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Java CompletableFuture如何实现超时功能

《JavaCompletableFuture如何实现超时功能》:本文主要介绍实现超时功能的基本思路以及CompletableFuture(之后简称CF)是如何通过代码实现超时功能的,需要的... 目录基本思路CompletableFuture 的实现1. 基本实现流程2. 静态条件分析3. 内存泄露 bug

C#实现添加/替换/提取或删除Excel中的图片

《C#实现添加/替换/提取或删除Excel中的图片》在Excel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更加美观,下面我们来看看如何在C#中实现添加/替换/提取或删除E... 在Excandroidel中插入与数据相关的图片,能将关键数据或信息以更直观的方式呈现出来,使文档更

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.