学习笔记-数据结构-线性表(2024-04-18)- 单向链表选择排序

试以单向链表为存储结构实现简单选择排序的算法。

实现递增排序,首先选择一个元素作为第一个比较值,遍历其他所有的元素,如果发现其他元素中有比它小的元素,则交换两个元素,这样每一趟都能找到符合要求的最小值

正经的单向链表排序,不是换数据的那种!
思想是选择排序的思想,但问题在于单链表结构不同于数组的直接交换,需要断链和重新成链等各种操作,稍不留神就直接G了

具体实现步骤如下

  • 初始化指针变量a和b,它们都指向链表的头节点。
  • 外层循环遍历链表,直到节点b是链表中的最后一个节点。
  • 内层循环遍历以节点b为起始的子链表,寻找其中最小的节点d。
  • 如果节点b的值大于节点d的值,说明需要将节点d插入到节点b之前。
  • 根据不同情况进行节点的移动和连接操作:
    • 如果节点d紧跟在节点b后面,分为两种情况:
      • 如果节点b是链表的头节点,则直接将节点d移动到节点b之前,并调整头节点的指针。
      • 如果节点b不是链表的头节点,则将节点d移动到节点b之前,并更新a的next指针。
    • 如果节点b和节点d之间有其他节点,也分为两种情况:
      • 如果节点b是链表的头节点,则将节点d移动到节点b之前,并更新头节点的指针。
      • 如果节点b不是链表的头节点,则将节点d移动到节点b之前,并更新a的next指针。
  • 完成内层循环后,更新a和b的指针,继续下一轮循环,直到整个链表都被排序完成。
  • 最后返回排序后的链表头节点。

下面是C语言写法:

typedef struct Node
{
    int data;
    struct Node *next;
}LinkNode;


LinkNode* selectionSort(LinkNode* head) 
{ 
    LinkNode *a, *b, *c, *d, *r; // 声明指针变量 a, b, c, d, r

    a = b = head; // 初始化指针变量 a, b,它们指向链表头部

    // 当 b 不是最后一个节点时执行循环
    while (b->next) { 

        c = d = b->next; // 初始化指针变量 c, d,它们指向 b 的下一个节点

        // 当 d 指向一个有效节点时执行循环
        while (d) { 

            if (b->data > d->data) { // 如果 b 的值大于 d 的值

                if (b->next == d) { // 如果 d 紧跟在 b 后面

                    if (b == head) { // 如果 b 是链表的头节点

                        // 将 d 移动到 b 的前面
                        b->next = d->next; 
                        d->next = b; 

                        // 交换 b 和 d 的指针
                        r = b; 
                        b = d; 
                        d = r; 

                        c = d; // 更新 c

                        // 更新链表头部
                        head = b; 

                        // 跳到下一个元素,因为它已经是有序的
                        d = d->next; 
                    } 
                    else { // 如果 b 不是链表的头节点

                        // 将 d 移动到 b 的前面
                        b->next = d->next; 
                        d->next = b; 
                        a->next = d; 

                        // 交换 b 和 d 的指针
                        r = b; 
                        b = d; 
                        d = r; 

                        c = d; // 更新 c

                        // 跳到下一个元素,因为它已经是有序的
                        d = d->next; 
                    } 
                } 
                else { // 如果 b 和 d 之间有一些非零节点

                    if (b == head) { // 如果 b 是链表的头节点

                        // 交换 b->next 和 d->next
                        r = b->next; 
                        b->next = d->next; 
                        d->next = r; 
                        c->next = b; 

                        // 交换 b 和 d 的指针
                        r = b; 
                        b = d; 
                        d = r; 

                        c = d; // 更新 c

                        // 跳到下一个元素,因为它已经是有序的
                        d = d->next; 

                        // 更新链表头部
                        head = b; 
                    } 
                    else { // 如果 b 不是链表的头节点

                        // 交换 b->next 和 d->next
                        r = b->next; 
                        b->next = d->next; 
                        d->next = r; 
                        c->next = b; 
                        a->next = d; 

                        // 交换 b 和 d 的指针
                        r = b; 
                        b = d; 
                        d = r; 

                        c = d; // 更新 c

                        // 跳到下一个元素,因为它已经是有序的
                        d = d->next; 
                    } 
                } 
            } 
            else { // 如果 b 的值不大于 d 的值

                // 更新 c 并跳到下一个元素,因为它已经是有序的
                c = d; 
                d = d->next; 
            } 
        } 

        a = b; // 更新 a
        b = b->next; // 更新 b
    } 

    return head; // 返回排序后的链表头部
} 

下面是Java语言写法:


public class Main {
  
    public static class Node {
        int data; 
        Node next; 
    };

    public static Node selectionSort(Node head)
    {
        Node a, b, c, d, r;
        a = b = head;
        while (b.next != null) {
            c = d = b.next;
            while (d != null) {
                if (b.data > d.data) {
                    if (b.next == d) {
                        if (b == head) {
                            b.next = d.next;
                            d.next = b;
                            r = b;
                            b = d;
                            d = r;
                            c = d;
                            head = b;
                            d = d.next;
                        }
                        else {
                            b.next = d.next;
                            d.next = b;
                            a.next = d;
                            r = b;
                            b = d;
                            d = r;
                            c = d;
                            d = d.next;
                        }
                    }
                    else {
                        if (b == head) {
                            r = b.next;
                            b.next = d.next;
                            d.next = r;
                            c.next = b;
                            r = b;
                            b = d;
                            d = r;
                            c = d;
                            d = d.next;
                            head = b;
                        }
                        else {
                            r = b.next;
                            b.next = d.next;
                            d.next = r;
                            c.next = b;
                            a.next = d;
                            r = b;
                            b = d;
                            d = r;
                            c = d;
                            d = d.next;
                        }
                    }
                }
                else {
                    c = d;
                    d = d.next;
                }
            }
            a = b;
            b = b.next;
        }
        return head;
    }

	// 新建Node节点
    static Node newNode(int val)
    { 
        Node temp = new Node(); 
  
        temp.data = val; 
  
        temp.next = null; 
  
        return temp; 
    } 
} 

示例

以 -2-0-0-3-5-1- 单链表为例
由于动态演示图较大,csdn无法上传,请移步至 https://gitee.com/xjk2000/image-storage/blob/master/1.gif
Java代码测试执行:
测试代码
执行结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

selenium 自动化测试课上实操指南1——百度搜索

1.环境准备 下面的所有资源可以从超星班级资料中下载,机房的同学在收到的文件夹中可以找到文件 非本校同学,免费加入学银在线课程,就可以在资料 根目录 > 02 课件新 > week09 web自动化测试02 里下载本次实操资料 1)安…

K8S探针分享

一,探针介绍 1 探针类型 livenessProbe:存活探针,用于判断容器是不是健康;如果探测失败,Kubernetes就会重启容器。 readinessProbe:就绪探针,用于判断是否可以将容器加入到Service负载均衡池…

使用Tortoise 创建远程分支

1。首先创建本地分支branch1,右键tortoise git->创建分支,输入分支名称branch1,确定。 2。右键tortoise git->推送,按下图设置,确定,git会判断远程有没有分支branch1,如果没有会自动创建…

C++学习随笔(11)——vector

本章我们来学习一下vector! 目录 1.vector的介绍及使用 1.1 vector的介绍 1.2 vector的使用 1.2.1 vector的定义 1.2.2 vector iterator 的使用 1.2.3 vector 空间增长问题 1.2.4 vector 增删查改 1.2.5 vector 迭代器失效问题。 1.vector的介绍及使用 1…

ANSYS WorkBench基础说明

1引入CAE产品设计流程 2有限元法简介 有限元法的基本概念:把一个原来是连续的物体划分为有限个单元,这些单元通过有限个节点相互连接,承受与实际载荷等效的节点载荷,根据力的平衡条件进行分析,并根据变形协调条件把这些单元重新组…

【Redis 开发】全局ID生成器

全局ID生成器 为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其他信息: ID的组成部分: 符号位:1bit,一直为0 时间戳:31bit,一秒为单位,可以使用69年 序列号:32bit,秒内…

idea 通过maven构建无法使用@SpringBootApplication

问题描述 SpringBootApplication标红,没有提示,无法启动springboot使用maven构建。通过idea的标准版本构建 原因 springboot构建启动依赖spring-boot-maven-plugin idea的标准版本没有指定构建版本,然后在springboot-parent里面没有指定默…

(已解决)PyQT5问题:控件和背景色同色,如何解决?

一、问题复现 难看到吐是不是 二、解决方案 拖动一个widget,设置其背景色,并且右键放到最后一层 三、解决结果 如上图所示 四、问题原因 直接在窗体右键设置背景色,由于Form是父类,即其下所有控件都与其同色,即使…

知识在人工智能中的核心作用:连接主义与符号主义的交融

知识在人工智能中的核心作用:连接主义与符号主义的交融 一、连接主义与深度学习的崛起二、感知与认知:AI的双眼与大脑三、知识的多元表示与处理四、符号主义与知识工程的实践五、知识在AI中的核心地位六、AI的具体应用案例分析七、知识图谱:认…

Linux多线程(一) 线程的创建与控制

一、线程概述 线程是轻量级的进程(LWP:light weight process),在Linux环境下线程的本质仍是进程。在计算机上运行的程序是一组指令及指令参数的组合,指令按照既定的逻辑控制计算机运行。操作系统会以进程为单位&#…

element-ui et -i 编译默认主题报错:ReferenceError: primordials is not defined

报错信息如下 fs.js:40 } primordials;^ ReferenceError: primordials is not defined导致这个问题的原因:node和gulp版本冲突!! 我使用的是node 14版本 解决方法: 看了好几个帖子,都推荐使用node 11.15.0版本&am…

css中新型的边框设置属性border-block

border-block 是 CSS 中的一个属性,主要用于在样式表中一次性设置元素的逻辑块向边框的属性值。这个属性是简写属性,可以同时设置 border-block-width、border-block-style 和 border-block-color。其中,border-block-start 用于设置元素的开…

物联网应用技术综合实训室解决方案

一、背景 随着物联网技术的快速发展和广泛应用,物联网产业已经成为新的经济增长点,对于推动产业升级、提高社会信息化水平具有重要意义。因此,培养具备物联网技术应用能力的高素质人才成为了迫切需求。 传统的教育模式往往注重理论教学&…

新科技辅助器具赋能视障生活:让盲人出行融入日常

随着科技日新月异的发展,一款名为蝙蝠避障专为改善盲人日常生活的盲人日常生活辅助器具应运而生,它通过巧妙整合实时避障与拍照识别功能,成功改变了盲人朋友们的生活格局,为他们提供了更为便捷、高效的生活体验。 这款非同…

DevOps(十五)如何创建参数化的Jenkins Job

一、Jenkins参数化 在Jenkins中创建参数化的Job允许你在构建过程中动态输入一些值,这样可以让构建过程更加灵活和通用。以下是创建参数化Jenkins Job的步骤: 1、 创建新的Job 登录到Jenkins控制台。点击左侧的“新建任务”或“Create new jobs”。输入…

RocketMQ 部署

RocketMQ 部署 1、安装依赖(Java) [rootMicroservices ~]# mkdir -p /data/businessServer/ [rootMicroservices ~]# cd /data/businessServer/# 获取安装包(下载较慢) [rootMicroservices businessServer]# wget https://githu…

【Redis 开发】(Feed流的模式,GEO数据结构,BitMap,HyperLogLog)

Redis FeedTimeline GEOBitMapHyperLogLog Feed Feed流产品有两种常见模式: Timeline:不做内容筛选,简单的按照内容发布时间排序,常用于好友或关注。例如朋友圈 优点:信息全面,不会有缺失。并且实现也相对简单 缺点:信息噪音较多&#xff0c…

「51媒体」城市推介会,地方旅游推荐,怎么做好媒体宣传

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 城市推介会和地方旅游推荐是城市形象宣传的重要组成部分,通过有效的媒体宣传可以提升城市的知名度和吸引力。: 一,活动内容层面: 突出亮点…

公认最好的随身WiFi的格行5G随身WiFi真实测评!格行5G和纽曼5G随身WiFi哪个好?5G随身WiFi推荐第一名

随着5G信号基站的铺设逐渐完善,各大通讯移动公司也都适时的推出了属于自己的5G随身WiFi。其中老牌企业纽曼与格行的5G随身WiFi最受大家的欢迎。那么二者到底谁才是5G设备中的王者呢?今天就做一个全面测评。 一、首先是颜值党们最为关注的外观问题 纽曼5…

Java中Synchronized的锁升级

锁升级过程 当JVM启动后,一个共享资源对象直到有线程第一个访问时,这段时间内是处于无锁状态,对象头的Markword里偏向锁标识位是0,锁标识位是01。 Tips:当一个共享资源首次被某个线程访问时,锁就会从无锁状…