单链表排序

单链表排序之选择排序 ***单链表排序之选择排序*** /* 前段时间刚学会几种排序方法,最近学习了单链表,就用来试试,本篇链表的排序方法讲述的是 单链表的选择排序;(注意:请仔细看准节点结构体的包装和头指针的包装再阅读以下代码); 选择排序的基本思想:对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小则 用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素” 阅读详情



单链表排序是单链表的常见编程任务之一,也是面试中经常出现的题目。单链表排序的关键是交换算法,需要额外考虑。选择排序是比较直观的排序算法之一,这里就使用选择排序实现单链表的排序。

如果需要对选择排序复习一下,传送门:算法导论:选择排序的原理与实现。

第一种方法:





LinkList SelectSort2(LinkList L)
{
    LinkList p,q,small;
    int temp;

    for(p = L->next; p->next != NULL; p = p->next)
    {
        small = p;
        for(q = p->next; q; q = q->next)
        {
            if(q->data < small->data)
            {
                small = q;
            }
        }
        printf("循环后,获得最小值为:%d, 此时链表为:", small->data);
        if(small != p) //这个判断经常会写漏,这样本身是最小值时,会做一次无用操作
        {
            temp = p->data;
            p->data = small->data;
            small->data = temp;
        }
        ListTraverse(L);
    }
    printf("输出排序后的数字:\n");
    return L;
}







第二种方法:




LinkList SelectSort(LinkList L)
{
    LinkList first;     /*排列后有序链的表头指针*/
    LinkList tail;      /*排列后有序链的表尾指针*/
    LinkList p_min;     /*保留键值更小的节点的前驱节点的指针*/
    LinkList min;       /*存储最小节点*/
    LinkList p;         /*当前比较的节点*/

    first = NULL;
    while (L != NULL) /*在链表中找键值最小的节点。*/
    {
        /*注意:这里for语句就是体现选择排序思想的地方*/
        for (p=L,min=L; p->next!=NULL; p=p->next) /*循环遍历链表中的节点,找出此时最小的节点。*/
        {
            if (p->next->data < min->data) /*找到一个比当前min小的节点。*/
            {
                p_min = p; /*保存找到节点的前驱节点:显然p->next的前驱节点是p。*/
                min = p->next; /*保存键值更小的节点。*/
            }
        }

        /*上面for语句结束后,就要做两件事;
            一是把它放入有序链表中;
            二是根据相应的条件判断,安排它离开原来的链表。*/

        /*第一件事*/
        if (first == NULL) /*如果有序链表目前还是一个空链表*/
        {
            first = min; /*第一次找到键值最小的节点。*/
            tail = min; /*注意:尾指针让它指向最后的一个节点。*/
        }
        else /*有序链表中已经有节点*/
        {
            tail->next = min; /*把刚找到的最小节点放到最后,即让尾指针的next指向它。*/
            tail = min; /*尾指针也要指向它。*/
        }
        /*第二件事*/
        if (min == L) /*如果找到的最小节点就是第一个节点*/
        {
            //printf("表头%d已经是最小,当前结点后移。\n", min->data);
            L = L->next; /*显然让head指向原head->next,即第二个节点,就OK*/
        }
        else /*如果不是第一个节点*/
        {
            p_min->next = min->next; /*前次最小节点的next指向当前min的next,这样就让min离开了原链表。*/
        }
    }
    if (first != NULL) /*循环结束得到有序链表first*/
    {
        tail->next = NULL; /*单向链表的最后一个节点的next应该指向NULL*/
    }
    L = first;
    return L;
}









完整的可执行程序:




#include "stdio.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

typedef struct Node
{
    ElemType data;
    struct Node *next;
} Node;
typedef struct Node *LinkList; /* 定义LinkList */

Status visit(ElemType c)
{
    printf("->%d",c);
    return OK;
}

/* 初始化顺序线性表 */
Status InitList(LinkList *L)
{
    *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
    if(!(*L)) /* 存储分配失败 */
        return ERROR;
    (*L)->next=NULL; /* 指针域为空 */

    return OK;
}

/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(LinkList L)
{
    int i=0;
    LinkList p=L->next; /* p指向第一个结点 */
    while(p)
    {
        i++;
        p=p->next;
    }
    return i;
}

/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(LinkList L)
{
    LinkList p=L->next;
    while(p)
    {
        visit(p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

/*  随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail(LinkList *L, int n)
{
    LinkList p,r;
    int i;
    srand(time(0));                      /* 初始化随机数种子 */
    *L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
    r=*L;                                /* r为指向尾部的结点 */
    for (i=0; i < n; i++)
    {
        p = (Node *)malloc(sizeof(Node)); /*  生成新结点 */
        p->data = rand()%100+1;           /*  随机生成100以内的数字 */
        r->next=p;                        /* 将表尾终端结点的指针指向新结点 */
        r = p;                            /* 将当前的新结点定义为表尾终端结点 */
    }
    r->next = NULL;                       /* 表示当前链表结束 */
}

LinkList SelectSort2(LinkList L)
{
    LinkList p,q,small;
    int temp;

    for(p = L->next; p->next != NULL; p = p->next)
    {
        small = p;
        for(q = p->next; q; q = q->next)
        {
            if(q->data < small->data)
            {
                small = q;
            }
        }
        printf("循环后,获得最小值为:%d, 此时链表为:", small->data);
        if(small != p)
        {
            temp = p->data;
            p->data = small->data;
            small->data = temp;
        }
        ListTraverse(L);
    }
    printf("输出排序后的数字:\n");
    return L;
}

LinkList SelectSort(LinkList L)
{
    LinkList first;     /*排列后有序链的表头指针*/
    LinkList tail;      /*排列后有序链的表尾指针*/
    LinkList p_min;     /*保留键值更小的节点的前驱节点的指针*/
    LinkList min;       /*存储最小节点*/
    LinkList p;         /*当前比较的节点*/

    first = NULL;
    while (L != NULL) /*在链表中找键值最小的节点。*/
    {
        /*注意:这里for语句就是体现选择排序思想的地方*/
        for (p=L,min=L; p->next!=NULL; p=p->next) /*循环遍历链表中的节点,找出此时最小的节点。*/
        {
            if (p->next->data < min->data) /*找到一个比当前min小的节点。*/
            {
                p_min = p; /*保存找到节点的前驱节点:显然p->next的前驱节点是p。*/
                min = p->next; /*保存键值更小的节点。*/
            }
        }

        /*上面for语句结束后,就要做两件事;
            一是把它放入有序链表中;
            二是根据相应的条件判断,安排它离开原来的链表。*/

        /*第一件事*/
        if (first == NULL) /*如果有序链表目前还是一个空链表*/
        {
            first = min; /*第一次找到键值最小的节点。*/
            tail = min; /*注意:尾指针让它指向最后的一个节点。*/
        }
        else /*有序链表中已经有节点*/
        {
            tail->next = min; /*把刚找到的最小节点放到最后,即让尾指针的next指向它。*/
            tail = min; /*尾指针也要指向它。*/
        }
        /*第二件事*/
        if (min == L) /*如果找到的最小节点就是第一个节点*/
        {
            //printf("表头%d已经是最小,当前结点后移。\n", min->data);
            L = L->next; /*显然让head指向原head->next,即第二个节点,就OK*/
        }
        else /*如果不是第一个节点*/
        {
            p_min->next = min->next; /*前次最小节点的next指向当前min的next,这样就让min离开了原链表。*/
        }
    }
    if (first != NULL) /*循环结束得到有序链表first*/
    {
        tail->next = NULL; /*单向链表的最后一个节点的next应该指向NULL*/
    }
    L = first;
    return L;
}

int main()
{
    LinkList L;
    Status i;
    char opp;
    ElemType e;
    int find;
    int tmp;

    i=InitList(&L);
    printf("初始化L后:ListLength(L)=%d\n",ListLength(L));

    printf("\n1.查看链表 \n2.创建链表(尾插法) \n3.链表长度 \n4.交换两个结点 \n0.退出 \n请选择你的操作:\n");
    while(opp != '0')
    {
        scanf("%c",&opp);
        switch(opp)
        {
        case '1':
            ListTraverse(L);
            printf("\n");
            break;

        case '2':
            CreateListTail(&L,10);
            printf("整体创建L的元素(尾插法):\n");
            ListTraverse(L);
            printf("\n");
            break;

        case '3':
            //clearList(pHead);   //清空链表
            printf("ListLength(L)=%d \n",ListLength(L));
            printf("\n");
            break;

        case '4':
            L = SelectSort2(L);
            //printf("%d \n", find);
            ListTraverse(L);
            printf("\n");
            break;

        case '0':
            exit(0);
        }
    }
}









第三种方法:冒泡排序





void MySwap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}
void BubbleSort(snode* head)//单链表的冒泡排序
{
	for (snode* i=head; i!=NULL; i=i->next)
	{
		for (snode* j=i; j!=NULL; j=j->next)
		{
			if (j->next && j->val < j->next->val)
				MySwap(j->val, j->next->val);
			if (j->next==NULL)
				MySwap(i->val, j->val);
		}
	}
}















链接:http://www.nowamagic.net/librarys/veda/detail/1852



单链表排序之冒泡排序 ***单链表排序之冒泡排序*** /* 前段时间刚学会几种排序方法,最近学习了单链表,就用来试试,本篇链表的排序方法讲述的是 单链表的冒泡排序;(注意:请仔细看准节点结构体的包装和头指针的包装再阅读以下代码); 冒泡排序的思想和冒泡排序数组的方法以及冒泡排序的优化,我都已经在冒泡排序的文章中介绍了; 冒泡排序链接:http://blog.csdn. 阅读详情

相关推荐

单链表快速排序

假设对一组序列进行升序快速排序. 对于数组进行快速排序的基本思想: 对于每一轮迭代, 选定一个目标元素key(通常选第一个)用来做partition, 定义两个指针left、right分别指向数组的头和尾, left指针从左往右移动, 遇到比key大的值暂停, right指针从右往左移动, 遇到比key小的值暂停, 两个指针都停下时交换两个指针指向的元素, 然后两个指针继续移动, 直到两个指针相遇...

啥都不会 1593

单链表排序(sort list)

昨晚被阿里在线笔试虐了,附加题完全不会,第二题

fmt.Println( 5097

SCI论文Discussion写作:如何用AI工具三步打造审稿人认可的深度逻辑框架

本文针对SCI论文Discussion写作的痛点,提出利用AI工具三步构建深度逻辑框架的方法。首先,使用Claude等工具搭建个性化提纲,解决“浅显病”与“混乱症”;其次,高效整合文献与结果,填充证据;最后,优化逻辑衔接与学术语言,打造审稿人认可的流畅论证。该方法强调研究者主导,AI辅助,显著提升写作效率与深度。

weixin_28235513的博客 233

单链表进行排序-通过节点交换,不通过值交换

原来我一直都不会对链表进行排序,呵呵,比较菜。今天下了很大的功夫学习对链表的排序,和大家分享一下!         对链表的排序主要有两种方法:         一:只交换节点中的元素,不改变链表的顺序。        二:直接交换节点,不改变节点中的元素。         其中交换节点是最麻烦的,稍不注意就会出错!而交换节点中的元素还是比较简单的。用几个swap( )就可

1万+

Dify 深度进阶:从入门到精通AI应用构建

《Dify进阶指南:从基础到高阶的AI应用开发技巧》 本文深入探讨Dify平台的高级功能与应用开发技巧。首先强调核心概念的深化,包括提示词工程进阶、知识库高效管理和模型参数优化。重点介绍智能体应用的开发方法,如何让AI具备自主规划与执行能力。同时讲解工作流编排、前端集成等实用技术,并分享应用运营优化、成本控制等实践经验。文章还展望了Dify生态的发展趋势,为开发者提供从基础到进阶的完整学习路径,助力打造更智能高效的AI应用。

同名公众号:dify实验室 1949

Windows MCP 安装教程:让 AI 代理与 Windows 系统无缝交互

通过以上步骤,你已经成功安装和配置了 Windows MCP 服务。现在你的 Cursor 编辑器可以通过 MCP 协议与 Windows 系统进行深度交互,AI 代理能够:启动和控制应用程序执行系统命令自动化 UI 操作获取系统状态信息这为 AI 辅助开发和工作流程自动化提供了强大的基础。如果你在使用过程中遇到任何问题,欢迎在评论区讨论或查看项目的官方文档。

chenchihwen的专栏 3349

【2.3】链式单链表

一、单链表的结构特征1、采用指针链接一些列的存储单元来存储数据2、动态分配存储空间3、插入或删除元素效率高4、查找元素效率低下单链表常见结构:2、文件组织方式3、linkList.h单链表函数声明文件#ifndef _YE_LELE_01 #define _YE_LELE_01 typedef int ElemType; typedef int Status; typedef struct LN...

yeler082的博客 489

增量编码器资讯大全

增量编码器是什么 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小,按照工作原理编码器可分为增量式和绝对式两类。 增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。 编码器是把角位移或直线位移转换成电信号的一种装置。前者称为码盘,后者称码尺.按照读出方式编码器可以分为接触式和非接触式两种.接触式采...

kindele的博客 6008

链表实现学生信息管理系统--数据结构(C语言)

**题目说明** 每个学生的信息包括:学号、姓名、性别、手机号码、数学分数、语文分数。程序使用链表结构完成以下管理功能: 创建链表 从键盘输入某个学生的信息,并将其插入链表中 从键盘输入某个学生的学号,并将其从链表中删除 对某个学生的信息的修改 查询符合某个条件(允许条件与或非组合)的学生,并打印查询结果 对学生按照某个信息进行排序并输出 扩展功能: 7. 支持从Excel表格导入学生数据 8. 支持将链表中的内容导出到Excel表格 9. 对人数、性别、分数支持简单的统计功能,如总体人数,男女比例,

xucan_123的博客 4930

R 绘制环形树状图

按大类小类的从属关系绘制环形图,并把不同值的节点设置为相应大小。要求同一类的节点应为同一颜色。 按照输入,处理代码和输出记录

weixin_43718786的博客 1872

lammps教程:非晶sio2建模方法

大家好,我是小马老师。 本文介绍非晶sio2的建模方法。 sio2的建模方法有很多,可以下载cif文件使用atomsk转为data文件,也可以直接在ms中导入sio2结构,这些方法建的sio2都是标准的sio2晶体。 如果要建立非晶状态的sio2,就是把排列规则的sio2变成无序排列的sio2。 非晶建模方法有很多,在lammps中,可以通过高温高压的方法打乱sio2的排列实现非晶建模。 代码中的温度和步数可根据需要自己调整。 下面给出in文件案例代码。 units metal atom

lammps_jiayou的博客 5264

对LinkedList进行排序

package 对Linked排序; public class Edge { public int w; public Edge() { // TODO 自动生成的构造函数存根 } public Edge(int w){ this.w=w; } public int getW() { return w; } public void setW(

u014230945的博客 1万+

PHM 2010数据集解读

PHM数据挑战赛是一项面向所有潜在与会者的竞赛。今年的挑战集中在使用测力仪、加速度计和声发射数据估计高速数控铣床刀具的RUL上。 博客对PHM 2010数据集的组成和信号进行了可视化。

cnjs1994的博客 7647

单链表的从小到大排序

#include<stdio.h> #include<stdlib.h> //单链表的存储结构定义 typedef struct Node { int data; struct Node *next; }LNode,*LinkList; //创建单链表 LinkList CreatList() { LinkList L; LNode *r,*s; int x; L=(LNode *)malloc(sizeof(LNode));//创建一个头结点 L->next

weixin_45701077的博客 1万+

.Net如何使用Web API实现数据交互?

数据模型代表了要交互的数据结构。例如,假设我们要创建一个简单的图书管理系统,我们可以定义一个Book类作为数据模型。set;set;set;

Code365 257

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

使用单链表的简单选择排序

单链表简单选择排序算法 单链表的存储结构和创建单链表 1、 单链表的结构: typedef struct list { int data; struct list * next; }list,*linklist; 2、 单链表的创建: void create(linklist &L,int n) { int i; linklist p; L = (linklist)ma...

weixin_43823538的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

C语言单链表冒泡排序

前言 大家在做学生成绩管理系统的时候,其中一个功能是要实现对学生的成绩从高到低排名,如果数据是存储在数组中的话,会很容易实现,但是这时成绩信息作为结构体成员被保存在单链表中,所以在每一轮交换排序的时候,地址不像数组那样可以简单通过下标转换而改变 所以在这里给大家分享下单链表的冒泡排序 。 冒泡排序 先说说冒泡排序的中心思想:通过对无序序列的相邻元素两两比较交换,每次把最大(小)的数据放在最后...

莫影 is Joker 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

详解单链表冒泡排序

C语言,对单链表进行冒泡排序

oTheodore的博客 2908

python单链表排序_单链表排序之选择排序

单链表排序是单链表的常见编程任务之一,也是面试中经常出现的题目。单链表排序的关键是交换算法,需要额外考虑。选择排序是比较直观的排序算法之一,这里就使用选择排序实现单链表的排序。C实现代码如下:LinkList SelectSort2(LinkList L){LinkList p,q,small;int temp;for(p = L->next; p->next != NULL; p =...

weixin_39613824的博客 723

单链表的排序

单链表的排序 题目描述 给定一个无序单链表,实现单链表的排序(按升序排序)。 代码 import java.util.*; /* * public class ListNode { * int val; * ListNode next = null; * } */ public class Solution { /** * * @param head ListNode类 the head node * @return ListNode类

chechenshi的博客 2192

单链表的选择排序

单链表的选择排序 题目描述 给定一个无序单链表,实现单链表的选择排序(按升序排序)。 输入描述: 第一行一个整数 n,表示单链表的节点数量。 第二行 n 个整数 val 表示单链表的各个节点。 输出描述: 在给出的函数内返回给定链表的头指针。 示例1 输入 5 1 3 2 4 5 输出 1 2 3 4 5 备注: 1≤n≤1061 \leq n \leq 10^61≤n≤106 −106≤val≤106-10^6 \leq val \leq 10^6−106≤val≤106 题解: 选择排序:在未排序

MIC10086的博客 690
上一篇: 单链表排序方法
下一篇: 寄存器某一位置位或者清零
tkp2014
博客等级 码龄12年 137粉丝 241原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值