单链表(二):如何实现单链表的排序、逆置(逆序)

2023-05-16

1、单链表的排序

示例代码如下:

#include<iostream>
using namespace std;
 
///单链表结构体:结点
typedef struct student
{
    int data;				//结点中的数据
    struct student *next;	//指向链表下一个结点的指针
}node;

node *head;	//头结点指针
int index;	//链表长度

///建立单链表
void *create()
{
    node *p,*s;	//增加结点的位置指针、要增加结点的指针
    int x,cycle=1;		//x是结点中的数据,若为0代表创建结束;cycle是循环控制变量
    head=(node*)malloc(sizeof(node)); //动态分配,建立头节点
    p=head;
    while(cycle)
    {
        printf("Please input the data:");
        scanf("%d",&x);
        if(x!=0)
        {
            s=(node*)malloc(sizeof(node));	//动态分配,每次新建一个节点
            s->data=x;						//将数据存入该结点
//			printf("%d\n",s->data);			//查看该结点中的数据是否正确
            p->next=s;						//连接头指针与当前结点
            p=s;							//并将头指针指向当前结点的指针,即下一个结点的地址
        }
        else
        {
            cycle=0;
        }
    }
    
    p->next=NULL;		//最后一个结点为空指针(必须)

//	head=head->next;	//创建完毕单链表,头结点指针回去
//	printf("\n   yyy   %d",head->data);	//打印第一个结点中的数据,用于验证

    return head;		//返回根结点
}

///遍历单链表(单链表打印),同时测长
//注:链表无法从反方向进行遍历
void traverse(node *head)
{
	node *p;
	index=0;
	if(head->next==NULL)
	{
		printf("Link is empty!\n");
		return;
	}
	p=head->next;
	while(p!=NULL)//遍历链表
	{
		printf("The %dth node is:%d\n",++index,p->data);//打印元素,亦可计算链表长度(index)
		p=p->next;//进入下一个结点
	}
	printf("\n该链表长度为:%d\n\n",index);
}

///单链表的排序
void *sort(node *head)
{
	node *p;
	int n=index;	//链表长度
	int temp;
	if(head==NULL || head->next==NULL)
		return head;

	p=head->next;	//p指向结点1,可以得到结点1的数据
	
	for(int j=1;j<n;j++) //冒泡排序
	{	
		p=head->next;	//每次冒泡过程完毕后,必须返回结点1
		for(int i=n-1;i>=j;i--)	//一次冒泡过程
		{
			if( (p->data) > (p->next->data) )	//从小到大排序
			{
				temp=p->data;
				p->data=p->next->data;
				p->next->data=temp;
			}
			p=p->next;
		}		
	}

	p=head->next;	//要打印排序好的链表,必须从头开始打印,也是遍历的一个过程
	//打印出排好序的链表(从小到大)
	for(int m=0;m<n;m++)
	{
		printf(" %d",p->data);
		p=p->next;
		
	}
	cout<<endl;
}
int main()
{
	cout<<"/***** 单链表的创建 *****/"<<endl;
	create();		//单链表的创建

	cout<<endl<<"/***** 单链表的遍历与测长 *****/"<<endl;
	traverse(head);	//单链表的遍历与测长

	cout<<endl<<"/***** 单链表的排序 *****/"<<endl;
	sort(head);	//单链表的排序

	return 0;
}

测试结果如图:



2、单链表的逆置(逆序)

单链表的逆置有2种方法,分别如下。

方法一:

基本思想:类似于冒泡法,但是不用比较数据大小,即可。


方法二:

基本思想:

(1)、单链表的模型如下图:


(2)、进行单链表的逆序,首先要让p2的next指向p1,如下图:


(3)、再由p1指向p2,p2指向p3,如下图:


然后重复p2的next指向p1,p1指向p2,p2指向p3。


完整的示例代码如下:

#include<iostream>
using namespace std;
 
///单链表结构体:结点
typedef struct student
{
    int data;				//结点中的数据
    struct student *next;	//指向链表下一个结点的指针
}node;

node *head;	//头结点指针
int index;	//链表长度

///建立单链表
void *create()
{
    node *p,*s;	//增加结点的位置指针、要增加结点的指针
    int x,cycle=1;		//x是结点中的数据,若为0代表创建结束;cycle是循环控制变量
    head=(node*)malloc(sizeof(node)); //动态分配,建立头节点
    p=head;
    while(cycle)
    {
        printf("Please input the data:");
        scanf("%d",&x);
        if(x!=0)
        {
            s=(node*)malloc(sizeof(node));	//动态分配,每次新建一个节点
            s->data=x;						//将数据存入该结点
//			printf("%d\n",s->data);			//查看该结点中的数据是否正确
            p->next=s;						//连接头指针与当前结点
            p=s;							//并将头指针指向当前结点的指针,即下一个结点的地址
        }
        else
        {
            cycle=0;
        }
    }
    
    p->next=NULL;		//最后一个结点为空指针(必须)

//	head=head->next;	//创建完毕单链表,头结点指针回去
//	printf("\n   yyy   %d",head->data);	//打印第一个结点中的数据,用于验证

    return head;		//返回根结点
}

///遍历单链表(单链表打印),同时测长
//注:链表无法从反方向进行遍历
void traverse(node *head)
{
	node *p;
	index=0;
	if(head->next==NULL)
	{
		printf("Link is empty!\n");
		return;
	}
	p=head->next;
	while(p!=NULL)//遍历链表
	{
		printf("The %dth node is:%d\n",++index,p->data);//打印元素,亦可计算链表长度(index)
		p=p->next;//进入下一个结点
	}
	printf("\n该链表长度为:%d\n\n",index);
}

///单链表的排序
void *sort(node *head)
{
	node *p;
	int n=index;	//链表长度
	int temp;
	if(head==NULL || head->next==NULL)
		return head;

	p=head->next;	//p指向结点1,可以得到结点1的数据
	
	for(int j=1;j<n;j++) //冒泡排序
	{	
		p=head->next;	//每次冒泡过程完毕后,必须返回结点1
		for(int i=n-1;i>=j;i--)	//一次冒泡过程
		{
			if( (p->data) > (p->next->data) )	//从小到大排序
			{
				temp=p->data;
				p->data=p->next->data;
				p->next->data=temp;
			}
			p=p->next;
		}		
	}

	p=head->next;	//要打印排序好的链表,必须从头开始打印,也是遍历的一个过程
	//打印出排好序的链表(从小到大)
	for(int m=0;m<n;m++)
	{
		printf(" %d",p->data);
		p=p->next;
		
	}
	cout<<endl;
}

///单链表的逆置:方法一
/*
注:链表无法从反方向进行遍历
方法一的基本思想:类似于冒泡法,但是不用比较数据大小即可。
*/

void *reverse1(node *head)
{
	node *p;
	int n=index;	//链表长度
	int temp;
	if(head==NULL || head->next==NULL)
		return head;

	p=head->next;	//p指向结点1,可以得到结点1的数据
	
	for(int j=1;j<n;j++) 
	{	
		p=head->next;	
		for(int i=n-1;i>=j;i--)
		{
			
			temp=p->data;
			p->data=p->next->data;
			p->next->data=temp;
			p=p->next;
		}		
	}

	p=head->next;

	//打印出逆置后的链表
	for(int m=0;m<index;m++)
	{
		printf(" %d",p->data);
		p=p->next;	
	}
}

///单链表的逆置:方法二
void *reverse2(node *head)
{
	node *p1,*p2,*p3;
	if(head==NULL || head->next==NULL)
		return head;

	p1=head;	//初始化p1是根结点
    p2=p1->next;//初始化p2是结点1
    while(p2)//当前结点的下一个结点是否为空
    {
        p3=p2->next;
        p2->next=p1;
        p1=p2;
        p2=p3;
    }
    head->next=NULL;
    head=p1;	

	//打印出逆置后的链表
	for(int m=0;m<index;m++)
	{
		printf(" %d",p1->data);
		p1=p1->next;
	}
	cout<<endl;
}

int main()
{
	cout<<"/***** 单链表的创建 *****/"<<endl;
	create();		//单链表的创建

	cout<<endl<<"/***** 单链表的遍历与测长 *****/"<<endl;
	traverse(head);	//单链表的遍历与测长

//	cout<<endl<<"/***** 单链表的排序 *****/"<<endl;
//	sort(head);	//单链表的排序

	cout<<endl<<"/***** 单链表的逆置:方法一 *****/"<<endl;
	reverse1(head);	//单链表的逆置:方法一

	cout<<endl<<"/***** 单链表的逆置:方法二 *****/"<<endl;
	reverse2(head);	//单链表的逆置:方法二

	return 0;
}

测试结果如下图:



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

单链表(二):如何实现单链表的排序、逆置(逆序) 的相关文章

  • Android app 后台被杀恢复

    android 模拟应用因内存不足被后台杀死命令 https www jianshu com p effb4546b9aa adb shell am kill all 应用通过home键已经停留在后台使用 xff0c 杀掉所有后台程序 xf
  • Ubuntu查看linux系统版本号

    查看ubuntu版本 输入命令 cat proc version 显示如下 Linux version 5 0 0 13 generic buildd 64 lcy01 amd64 020 linux内核版本号 gcc version 8
  • Linux C Socket简介和实现

    1 网络中进程之间如何通信 xff1f 本地的进程间通信 xff08 IPC xff09 有很多种方式 xff0c 但可以总结为下面4类 xff1a 消息传递 xff08 管道 FIFO 消息队列 xff09 同步 xff08 互斥量 条件
  • C++ STL视频教程,初学者必备视频资料

    STL视频教程 初学者必备视频资料 我一个朋友做的 我转发到这里和大家分享 STL语音视频教程 下载地址 xff1a url 61 http www ctdisk com file 3388918 STL语音视频教程 7z url
  • QMessageBox简单用法(QT5.12)

    span class token comment for starf study span span class token macro property span class token directive hash span span
  • TOF相机 Realsense L515 与 Ipad pro Lidar Camera 对比

    最近好奇都是TOF 相机 L5151 和 Ipad pro 上带的深度相机模块有啥不一样 网上很少有相关的中文资料来介绍 原理上的差异 简单搜索了一下 在此小小总结 Apple Lidar Camera 苹果采用的激光是 VCSEL Ver
  • Arduino 读取GPS 数据发送解析并发布ROS topic(一)

    概述 通过Arduino收集GPS数据 xff0c 连接至电脑端 xff0c 在电脑端通过python对数据进行整理 xff0c 并通过发布 TOPIC xff0c 本部分主要记录如何通过Arduino读取GPS数据 接线方式 GPS 的
  • STM32 复位电路设计

    在此之前我是个只会抄写原理图的工程师 xff0c 每当遇到一个问题时 xff0c 确需要解决很久 xff0c 最根本的原因在于不明白其中的原理 xff0c 这次补充一下单片机复位电路设计 1 为什么要设计复位电路 xff1f 在做一件事情之
  • STM32核心板设计——电源设计

    1 STM32 数据手册电源部分研读 RTC电源管脚为V BAT 电源范围为1 8 3 6V xff0c 主要用于RTC时钟的供电 xff0c RTC在大部分场合用于保存一些重要的参数 xff0c 比如在电脑主板上用于保存boss的信息 x
  • stm32的复位电路问题

    现在比较流行的复位方式是这样的 xff1a 但我们都知道对于结构紧凑型硬件来说 xff0c 多一个电阻都是没必要的 在没有手动复位需求的场合 xff0c 能不能删掉按键与R24 xff0c 仅保留104电容 xff1f 通过阅读stm32
  • 外设驱动库开发笔记21:BME680环境传感器驱动

    环境传感器是一类我们很常用的传感器 它可以方便我们获取压力 温度 湿度以及空气质量等数据 在这一篇中 xff0c 我们将分析 BME680 环境传感器的功能 xff0c 并设计和实现 BME680 环境传感器的驱动 1 功能概述 BME68
  • 外设驱动库开发笔记45:MS4515DO压力传感器驱动

    很多时候我们需要检测流量和压力这些参数 xff0c 比如我们要检测大气压 xff0c 或者通过测量差压来获得输送流体的流量等 xff0c 都需要用到压力传感器 这一篇我们就来讨论MS4515DO压力传感器的数据获取 1 功能概述 MS451
  • 一个好看的CSS样式表格

    一个好看的CSS样式表格 自动换整行颜色的CSS样式表格 xff08 需要用到JS xff09 自动换整行颜色的CSS样式表格源代码 自动换整行颜色的CSS样式表格 xff08 需要用到JS xff09 这个CSS表格会自动切换每一行的颜色
  • docker删除镜像

    docker要删除镜像 xff0c 先要删除依赖它的容器 1 删除容器 docker ps 查看正在运行的容器 docker ps a 查看所有容器 docker rm container id 删除容器 2 删除镜像 docker ima
  • FreeRTOS如何结束和重新启动调度程序

    大多数主机或桌面系统 xff08 比如Linux xff0c Mac或Windows xff09 都有一个正常的用例 xff0c 你可以在早上启动操作系统 xff0c 然后在晚上关闭它 xff0c 然后你就离开机器 嵌入式系统是不同的 xf
  • [显存被占满,程序无法运行问题]ResourceExhaustedError (see above for traceback): OOM when allocating tensor

    最近在实验室的服务器上跑tensorflow程序 xff0c 一直都没有报错 xff0c 但是今天却突然报错 xff0c 而且出错提示显示的内容从未见到过 xff0c 错误提示如下 xff1a 错误提示资源耗尽 xff0c 无法分配tens
  • 解读神经网络十大误解,再也不会弄错它的工作原理(转载自机器之心)

    神经网络是机器学习算法中最流行和最强大的一类 在计量金融中 xff0c 神经网络常被用于时间序列预测 构建专用指标 算法交易 证券分类和信用风险建模 它们也被用于构建随机过程模型和价格衍生品 尽管神经网络有这些用处 xff0c 但它们却往往
  • 树莓派 Raspberry Pi VNC屏幕无法显示、软键盘、摄像头实时图传、固定IP等环境配置

    目录 1 VNC屏幕无法显示 2 树莓派软键盘安装 3 摄像头实时图传配置 xff0c 可用于图像监控系统 4 安装VIM与固定IP 1 VNC屏幕无法显示 在树莓派终端 xff0c 输入 sudo raspi config 选择接口配置
  • 在Jetson上配置RealSense相机驱动

    1 下载源码 https github com IntelRealSense librealsense span class token builtin class name cd span librealsense scripts set
  • aruco marker使用笔记

    在英伟达Jetson Xaiver开发板上配置 SDK环境 opencv 4 1 1 CUDA 10 2 1 git clone https github com pal robotics aruco ros 2 复制到catkin ws

随机推荐

  • catkin_make命令

    catkin make是在catkin工作区中构建代码的便捷工具 catkin make遵循catkin工作区的标准布局 xff0c 如REP 128中所述 用法 假设您的catkin工作区位于 catkin ws中 xff0c 则应始终在
  • docker容器中运行界面程序

    Docker比较常用的场景是 运行无界面的后台服务 或者 运行Web服务 不过有时出于个人的喜好或特定的需求 xff0c 我们会希望在Docker中运行带图形界面的应用程序 将容器中的图形界面展示到外部的一般性思路 xff1a 目前Unix
  • linux录屏

    Linux下好用的录屏软件是kazam录屏后视频处理软件kdenlive根据剪辑好的视频撰写解说词 xff0c 使用讯飞配音app将解说词文字转换为语音mp3将语音与视频通过kdenlive软件合成在一起 xff0c 完美的演示视频诞生了
  • 【python】conda和pip安装库之间的区别

    conda 首先 xff0c conda是一个通用的包管理器 xff0c 意思是什么语言的包都可以用其进行管理 xff0c 自然也就包括Python了 在安装Anaconda或者Miniconda时 xff0c 会对conda进行一同安装
  • OpenHarmony-Overview_zh

    OpenHarmony开源项目 项目介绍 OpenHarmony是开放原子开源基金会 xff08 OpenAtom Foundation xff09 旗下开源项目 xff0c 定位是一款面向全场景的开源分布式操作系统 OpenHarmony
  • 【python量化】用时间卷积神经网络(TCN)进行股价预测

    写在前面 下面这篇文章首先主要简单介绍了目前较为先进的时间序列预测方法 时间卷积神经网络 xff08 TCN xff09 的基本原理 xff0c 然后基于TCN的开源代码 xff0c 手把手教你如何通过时间卷积神经网络来进行股价预测 xff
  • 【python量化】将Transformer模型用于股票价格预测

    写在前面 下面的这篇文章主要教大家如何搭建一个基于Transformer的简单预测模型 xff0c 并将其用于股票价格预测当中 原代码在文末进行获取 1 Transformer模型 Transformer 是 Google 的团队在 201
  • 解读:基于GCN的股票预测模型

    前言 xff1a 自ICLR2017首次提出图卷积神经网络 xff08 GCN xff09 的概念 xff0c 该模型在节点分类 边预测等任务上表现出了出色的性能 在传统因子选股模型中 xff0c 常常将股票视为独立的个体 xff0c 但事
  • 【python量化】基于backtrader的深度学习模型量化回测框架

    写在前面 在本文中 xff0c 我们将介绍使用PyTorch构建一个深度学习模型 xff0c 并将其集成到backtrader回测框架中 具体地 xff0c 我们将使用PyTorch来实现一个长短期记忆神经网络 xff08 LSTM xff
  • 【量化交易】股票价格前复权与后复权的区别以及注意事项

    时不时就会看到到底是用股票前复权还是后复权价格的讨论 xff0c 比如下面就是一个很经典的问法 xff1a 我用前复权价格计算指标的时候 xff0c 发现会出现负价格 xff0c 就没法取log了 xff0c 应该是分红太多导致的 xff0
  • skfuzzy.cmeans与sklearn.KMeans聚类效果对比以及使用方法

    因为实验中要用到聚类效果的对比 xff0c 没有时间自己来实现算法 xff0c 所以Kmeans就用到了sklearn中的Kmeans类 xff0c FCM用到了skfuzzy cmeans 几个概念 1 Kmeans Kmeans是聚类算
  • 对论文中模型进行编程实现时的注意要求和总结

    看论文时 xff0c 如果论文中有对自己研究方向有帮助或者具有实际用处的模型时 xff0c 不免通过编程对其进行实现 如果是一个简单的模型 xff0c 用个caffe tensorflow之类的框架跑跑就出来的那就无所谓了 xff0c 但是
  • 机器学习里面的Ground Truth是什么意思

    在看英文文献的时候 xff0c 经常会看到Ground Truth这个词汇 xff0c 翻译的意思是地面实况 xff0c 放到机器学习里面 xff0c 再抽象点可以把它理解为真值 真实的有效值或者是标准的答案 维基百科对Ground Tru
  • python 字符串(str)与列表(list)以及数组(array)之间的转换方法详细整理

    前提 xff1a list以及array是python中经常会用到的数据类型 xff0c 当需要对list以及array进行文件的读写操作的时候 xff0c 由于write函数参数需要的是一个str xff0c 所以这时就需要对list或者
  • RMSE(均方根误差)、MSE(均方误差)、MAE(平均绝对误差)、SD(标准差)

    RMSE xff08 Root Mean Square Error xff09 均方根误差 衡量观测值与真实值之间的偏差 常用来作为机器学习模型预测结果衡量的标准 MSE xff08 Mean Square Error xff09 均方误差
  • LINUX——FIREWALLD防火墙基础(FIREWALLD-CMD命令操作+FIREWALLD-CONFIG图形管理工具)

    LINUX FIREWALLD防火墙基础 xff08 FIREWALLD CMD命令操作 43 FIREWALLD CONFIG图形管理工具 xff09 前言一 FIREWALLD概述1 1 FIREWALLD1 2 FIREWALLD和I
  • 时间序列分析之ADF检验

    ADF检验 在使用很多时间序列模型的时候 xff0c 如 ARMA ARIMA xff0c 都会要求时间序列是平稳的 xff0c 所以一般在研究一段时间序列的时候 xff0c 第一步都需要进行平稳性检验 xff0c 除了用肉眼检测的方法 x
  • pandas之分组groupby()的使用整理与总结

    文章目录 前言准备基本操作可视化操作REF 前言 在使用pandas的时候 xff0c 有些场景需要对数据内部进行分组处理 xff0c 如一组全校学生成绩的数据 xff0c 我们想通过班级进行分组 xff0c 或者再对班级分组后的性别进行分
  • 【vn.py】源码解析之 Dual Thrust 策略

    文章目录 Dual Thrust 策略Dual Thrust 策略源码分析1 完整源码2 策略参数与变量3 策略执行逻辑 Dual Thrust 策略 Dual Thrust 策略是 Michael Chalek 在80 年代开发的一种通道
  • 单链表(二):如何实现单链表的排序、逆置(逆序)

    1 单链表的排序 示例代码如下 xff1a include lt iostream gt using namespace std 单链表结构体 xff1a 结点 typedef struct student int data 结点中的数据