以往博客的复习补充——part1

之前没更新是因为期末考试要复习,没空写博客。1月3号才考完,现在有空,打算从头看一遍,既是复习以前知识点,又是对原来的博客进行补充。刚好寒假,有大把时间。

一,希尔排序(Shell Sort)

算是插入排序的改进。因为插入算法相比三傻排序的另外两个,在序列有序时能够节省时间复杂;而且插入排序会在数据量比较小的时候效率比较高。所以通过增量将数组进行分组,开始增量较大,每组数据量较小,很快就能排有序。然后逐渐缩小增量,在分组内进行插入排序。直至增量为1.

还有就是增量是多少,就会分为几个组。因为一个组内两个元素的间隔为增量,中间就会夹着增量个元素,意味着还要分多少组。

希尔排序也叫作缩小增量排序。在排序过程中开始分组多但组内元素少,后来分组少元素多,但是越来越有序的。

具体过程看下面教程或者b站视频《数据结构合集——希尔排序》蓝不过海呀。

六大排序算法:插入排序、希尔排序、选择排序、冒泡排序、堆排序、快速排序-CSDN博客

我写下代码:

第一次写的,只能说是漏洞百出,不忍直视。

#include<stdio.h>int main()
{int arr[] = { 3,2,4,9,6,1,5,7,8 };int len = sizeof(arr) / sizeof(int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}printf("\n");int gap = len / 2;int turn = 2;while (turn){//当前增量下,会分为几组,也就会进行几轮插入排序。for (int i = 0; i < (len / gap); i++){int end = i;//end是有序队列末尾。int temp = arr[end + gap];//temp临时变量代表将要插入的元素。//接下来就是组内进行插入排序。while (end >= 0){if (arr[end] > temp){arr[end + gap] = arr[end];//大于插入元素的往后移,它的位置空出来了。end -= gap;}else break;}arr[end + gap] = temp;}//接下来更新增量,进行下一轮排序。gap /= 2;if (gap == 1) turn--;//第一次gap等于1时循环不会结束。}printf("end");for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}

这是AI分析出的问题:
 

问题 1:分组逻辑有误

在 for (int i = 0; i < (len / gap); i++) 这一部分,你的分组逻辑错误。希尔排序的核心思想是在当前增量 gap 下,对所有以 gap 为间隔的元素分组,然后对每组进行插入排序。这里你按 (len / gap) 的方式分组,但实际上应该从每个分组的起始点出发进行分组,即从 0 到 gap - 1 的每个起点出发。


问题 2:组内插入排序逻辑有误

int end = i;  // end 是有序队列的末尾
int temp = arr[end + gap];

这里 end 设置为 i 是不正确的,因为在希尔排序中,组内的有序序列需要从当前分组起点逐步扩展,而不是简单地以分组的索引作为 end

正确的逻辑是从当前分组的起始点出发,按增量 gap 逐步移动进行插入排序。


问题 3:增量更新逻辑有误

你的增量更新逻辑是:

gap /= 2;
if (gap == 1) turn--;

这里你设置了一个变量 turn,试图在 gap == 1 时多循环一次。但这是不必要的,希尔排序的结束条件应当是 gap == 0,即在最后一次增量为 1 的插入排序完成后结束。

这是我自己改的代码

#include<stdio.h>int main()
{int arr[] = { 3,2,4,9,6,1,5,7,8 };int len = sizeof(arr) / sizeof(int);for (int i = 0; i < len; i++){printf("%d ", arr[i]);}printf("\n");int gap = len / 2;while (gap){//当前增量下,会分为几组,也就会进行几轮插入排序。for (int i = 0; i < gap; i++){int end = i;//end是有序队列末尾。从开始序号为i这组进行插入排序。while (end + gap < len){int temp = arr[end + gap];//temp临时变量代表将要插入的元素。//接下来就是组内进行插入排序。while (end >= 0){if (arr[end] > temp){arr[end + gap] = arr[end];//大于插入元素的往后移,它的位置空出来了。end -= gap;}else break;}arr[end + gap] = temp;end += gap;}}//接下来更新增量,进行下一轮排序。gap /= 2;}for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}

这是AI的答案

#include <stdio.h>int main()
{int arr[] = { 3, 2, 4, 9, 6, 1, 5, 7, 8 };int len = sizeof(arr) / sizeof(int);// 打印初始数组for (int i = 0; i < len; i++){printf("%d ", arr[i]);}printf("\n");// 希尔排序int gap = len / 2;  // 初始增量为数组长度的一半while (gap > 0){// 从每组的起点出发for (int i = gap; i < len; i++){int temp = arr[i];  // 当前待插入的元素int j = i;// 插入排序:对当前组进行排序while (j >= gap && arr[j - gap] > temp){arr[j] = arr[j - gap];  // 元素后移j -= gap;}arr[j] = temp;  // 插入到正确位置}gap /= 2;  // 缩小增量}// 打印排序后的数组for (int i = 0; i < len; i++){printf("%d ", arr[i]);}return 0;
}

ai这个好理解,将每组起点过后的元素进行插入排序,因为增量的存在,所以插入排序只会和自己所在组的进行比较。

另位博主写的代码

//希尔排序
void ShellSort(int* arr, int n)
{int gap = n;while (gap>1){//每次对gap折半操作gap = gap / 2;//单趟排序for (int i = 0; i < n - gap; ++i){int end = i;int tem = arr[end + gap];while (end >= 0){if (tem < arr[end]){arr[end + gap] = arr[end];end -= gap;}else{break;}}arr[end + gap] = tem;}}
}

二,链表相加

以前写的

Node* add_twolist(Node* head1, Node* head2)
{Node* ans, * current, * cur1 = head1, * cur2 = head2;ans = current = NULL;int carry = 0;for (int sum, val;cur1 != NULL || cur2 != NULL;cur1 = (cur1 == NULL) ? NULL : cur1->next,cur2 = (cur2 == NULL) ? NULL : cur2->next){sum = (cur1 == NULL ? 0 : cur1->value)+ (cur2 == NULL ? 0 : cur2->value)+ carry;val = sum % 10;carry = sum / 10;if (ans == NULL)//create the new head node {ans = new Node(val);current = ans;}else{current->next = new Node(val);current = current->next;}}if (carry == 1)current->next = new Node(1);return ans;
}

这是复习时写的

Node* add_list(Node* h1, Node* h2)
{Node* head, * current;int value, carry;value = (h1->value + h2->value) % 10;carry = (h1->value + h2->value) / 10;head = current = new Node(value);h1 = h1->next;h2 = h2->next;while (h1 && h2){value = (h1->value + h2->value + carry) % 10;carry = (h1->value + h2->value + carry) / 10;Node* p = new Node(value);current->next = p;current = current->next;h1 = h1->next;h2 = h2->next;}while (h1){value = (h1->value + carry) % 10;carry = (h1->value + carry) / 10;Node* p = new Node(value);current->next = p;current = current->next;h1 = h1->next;}while (h2){value = (h2->value + carry) % 10;carry = (h2->value + carry) / 10;Node* p = new Node(value);current->next = p;current = current->next;h2 = h2->next;}if (carry){Node* p = new Node(carry);current->next = p;current = current->next;}return head;
}

三,分割链表

第一次

Node* seperate_list(Node* head, int target)
{Node* h1, * h2, * cur1, * cur2;h1 = cur1 = NULL;h2 = cur2 = NULL;while (head){if (head->value <= target){if (!h1)h1= head;else{cur1->next = head;cur1 = cur1->next;}}else{if (!h2)h2 = cur2 = head;else{cur2->next = head;cur2 = cur2->next;}}head = head->next;}cur1->next = h2;return h1;
}

能看出哪里有问题吗?

首先是两条链表赋值时,只让h1 = head,此时cur1还是NULL;

cur2的next可能没有指向空,导致打印链表时出现死循环。

例如数组int arr[] = { 3,2,6,5,4,7,1 };

还有第三个错误就是没有新造链表,直接使用原链表,原链表的节点之间的联系还没有解开,关系混乱。

改后

Node* seperate_list(Node* head, int target)
{Node* h1, * h2, * cur1, * cur2;h1 = cur1 = NULL;h2 = cur2 = NULL;while (head){if (head->value < target){if (!h1)h1 = cur1 = new Node(head->value);else{cur1->next = new Node(head->value);cur1 = cur1->next;}}else if(head->value > target){if (!h2)h2 = cur2 = new Node(head->value);else{cur2->next = new Node(head->value);cur2 = cur2->next;}}head = head->next;}cur1->next = new Node(target);cur1 = cur1->next;cur1->next = h2;if (!cur2) cur2->next = NULL;return h1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501975.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32-C3环境搭建

参考第二讲 ubuntu下的ESP-IDF开发环境搭建_哔哩哔哩_bilibili 宸芯IOT中的资料搭建 因为我买的板子是ESP32C3&#xff0c;所以没有完全按照教程去设置环境&#xff0c;但是也成功。 一、下载ubuntu系统以及esp-idf https://cn.ubuntu.com/download/server/step1 在以上链接…

解决npm报错:sill idealTree buildDeps

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 报错信息 使用 npm 安装依赖时报错&#xff1a;sill idealTree buildDeps 解决方案 请按照以下步骤进行相关操作&#xff1a; 1、删除 C:\Users{账户}\ 文件夹中的 .npm…

【NX入门篇】

NX入门篇 一、UG NX 由来二、软件如何启动&#xff08;UG NX 12.0&#xff09;三、使用步骤四、常用命令 一、UG NX 由来 UG NX由来&#xff1a; 1969 年&#xff1a;UG 的开发始于美国麦道航空公司&#xff0c;基于 C 语言开发实现&#xff1b;1976 年&#xff1a;UG问世&am…

如何在 VSCode 中配置 C++ 开发环境:详细教程

如何在 VSCode 中配置 C 开发环境&#xff1a;详细教程 在软件开发的过程中&#xff0c;选择一个合适的开发环境是非常重要的。Visual Studio Code&#xff08;VSCode&#xff09;作为一款轻量级的代码编辑器&#xff0c;凭借其强大的扩展性和灵活性&#xff0c;受到许多开发者…

超越YOLO11!DEIM:先进的实时DETR目标检测

DEIM: DETR with Improved Matching for Fast Convergence arXiv: https://arxiv.org/abs/2412.04234 Project webpage&#xff1a;https://www.shihuahuang.cn/DEIM/ GitHub&#xff1a;https://github.com/ShihuaHuang95/DEIM 1 背景&#xff1a;DETR目标检测框架 目标检…

《GICv3_Software_Overview_Official_Release_B》学习笔记

1.不同版本的 GIC 架构及其主要功能如下图所示&#xff1a; 2.GICv2m&#xff08;Generic Interrupt Controller Virtualization Model&#xff09;是针对ARM架构的GIC&#xff08;通用中断控制器&#xff09;的一种扩展&#xff0c; GICv2m扩展为虚拟化环境中的中断管理提供了…

PADS Logic原理图中有很多页原理图,如何(怎样)删除其中一页或者多页

我们在进行PADS Logic进行原理图设计的时候&#xff0c;有时候可能遇到一次性设计了很多页的原理图&#xff0c;比如说十几页的原理图。那么我们在进行PADS Layout的时候&#xff0c;可能将这些原理图绘制两块板或者多块PCB板&#xff0c;那么这时候我们需要将其中的一张原理图…

网络安全的学习与实践经验(附资料合集)

学习资源 在线学习平台&#xff1a; Hack This Site&#xff1a;提供从初学者到高级难度的挑战任务&#xff0c;适合练习各种网络安全技术。XCTF_OJ&#xff1a;由XCTF组委会开发的免费在线网络安全网站&#xff0c;提供丰富的培训材料和资源。SecurityTube&#xff1a;提供丰…

问题清除指南|关于num_classes与 BCELoss、BCEWithLogitsLoss 和 CrossEntropyLoss 的关系

前言&#xff1a;关于「 num_classes 1 」引发的探究。 2024年尾声&#xff0c;学弟问到一个问题&#xff1a;在研究工作 CNNDetection 的github开源代码 networks/trainer.py 文件的 line 27 self.model resnet50(num_classes1) 中&#xff0c;变量 num_classes 的值为1&…

CSS——1.优缺点

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title></title><link rel"stylesheet" type"text/css" href"1-02.css"/></head><body><!--css&#xff1a;层叠样式表…

ETCD渗透利用指南

目录 未指定使用put操作报错 未指定操作版本使用get报错 首先etcd分为两个版本v2和v3&#xff0c;不同的API结果无论是访问URL还是使用etcdctl进行通信&#xff0c;都会导致问题&#xff0c;例如使用etcdctl和v3进行通信&#xff0c;如果没有实名ETCDCTL_API3指定API版本会直接…

开源数据集成平台白皮书重磅发布《Apache SeaTunnel 2024用户案例合集》!

2025年新年临近&#xff0c;Apache SeaTunnel 社区用户案例精选&#x1f4d8;也跟大家见面啦&#xff01;在过去的时间里&#xff0c;SeaTunnel 社区持续成长&#xff0c;吸引了众多开发者的关注与支持。 为了致谢一路同行的伙伴&#xff0c;也为了激励更多人加入技术共创&…

【RTD MCAL 篇3】 K312 MCU时钟系统配置

【RTD MCAL 篇3】 K312 MCU时钟系统配置 一&#xff0c;文档简介二&#xff0c; 时钟系统理论与配置2.1 K312 时钟系统2.1.1 PLL2.1.2 MUX_0系统2.1.3 MUX_6 时钟输出2.1.4 option B推荐方案 2.2 EB 配置2.2.1 General 配置2.2.2 McuClockSettingConfig配置2.2.2.1 McuFIRC配置…

vite-plugin-imagemin安装问题

vite-plugin-imagemin 是一款图片资源压缩插件,能够在打包的时候显著的降低图片资源占用。不过,在安装过程中我们遇到了如下的问题。 对于上面的问题,有以下几种常见的解决方案: 1,使用 yarn 在 package.json 内配置(推荐) 打开 package.json 配置文件,然后添加如下脚本…

c-动态内存管理 (动态内存管理比较深入的分析和理解博客总结)

本节博客主要是堆C语言动态内存管理进行一定深度的谈论, 主要谈论主题请见目录~ 目录 1. 复习 与 铺垫(动态内存管理基本知识)1.1 什么是动态内存管理(基本代码)?1.2 为什么要有动态内存管理?1.3 什么是野指针? 2. C程序地址空间分布2.1 两者的空间是如上图所示的吗? 我们验…

【JVM】总结篇-运行时内存篇

文章目录 JVM内存模型&#xff08;内存结构&#xff09;程序计数器 pc虚拟机栈本地方法栈 native堆堆空间堆中一些JVM参数堆中垃圾回收过程MinorGC MajorGC FullGC年轻代GC(Minor GC)触发机制&#xff1a;老年代GC&#xff08;Major GC/Full GC&#xff09;触发机制&#xff1a…

Tableau数据可视化与仪表盘搭建-安装教程

下载 tableau.com/zh-cn/support/releases 滚动到最下方的下载 在下载的同时 我们点击登录&#xff0c;去注册一个tableau的账号 下面点击我们下载好的tableau安装程序 不要自定义安装&#xff0c;会有路径问题 点击试用14天 点击激活 激活学生 tableau.com/zh-cn/academic…

GitHub的简单操作

引言 今天开始就要开始做项目了&#xff0c;上午是要把git搭好。搭的过程中遇到好多好多的问题。下面就说一下git的简单操作流程。我们是使用的GitHub,下面也就以这个为例了 一、GitHub账号的登录注册 https://github.com/ 通过这个网址可以来到GitHub首页 点击中间绿色的S…

【2025最新计算机毕业设计】基于Spring Boot+Vue影院购票系统(高质量源码,提供文档,免费部署到本地)

作者简介&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容&#xff1a;&#x1f31f;Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

数据安全防护

数据安全防护有几个层面 边界安全 网络防火墙负责的部分 认证 kerberos负责的部分 授权 识别用户是否有访问某个模块的权限 认证是kerberos负责的事情 1. 客户端请求认证服务器&#xff0c;希望得到访问服务端票据的票据 2.客户端拿到访问服务端票据的票据后&#xff0c;去…