单链表排序(移动节点)

单链表排序利用了选择排序的方式;
创建一个单链表结构体

typedef int data_t;//为了能适应存储其他类型数据,可以将int换成其他数据类型而不通用一个一个更改程序里的了typedef struct node{data_t a;//链表里存的数据struct node *next;//指向下一个节点
}linknode,* linklist;//创建结构体变量和指针

单链表节点的结构形式出来啦,接下来我们就按图施工,创建链表吧

linklist link_creart(){linklist H;H = (linklist)malloc(sizeof(linknode));//为链表节点申请内存if(H == NULL){printf("malloc is fail\n");return H;}H->a = 0;//第一个作为头节点不存数据随便写个值H->next = NULL;//后续节点还没有只能是空return H;
}

空链表不能饿着肚子需要填一些东西进去,那么我们就写个函数喂一下这个链表吧。

int link_insert_last(linklist H,data_t value){//采取尾部插入的方式填充链表linklist p;linklist q;p = H;q = (linklist)malloc(sizeof(linknode));//为每个插入的节点申请内存if(q == NULL){printf("creart new node fail\n");return 0;}q->a = value;//输入我们需要存储的值q->next = NULL;//注意:最后一个节点的next需要为NULL,因为我们采用尾部插入,所以新建的节点next=NULLwhile(p->next != NULL){//找到最后一个节点p = p->next;}p->next = q;return 1;
}

利用link_insert_last(linklist H,data_t value)函数如果这样操作是不是太麻烦了呢

link_insert_last(linklist H,data_t 1);
link_insert_last(linklist H,data_t 2);
link_insert_last(linklist H,data_t 3);
link_insert_last(linklist H,data_t 4);

那我们换个方法

data_t a;
while(1){scanf("%d",&a);if(a == -1){  //输入-1停止输入break;}link_insert_last(H,a);}

有了输入我们还需要看一下,是不是输入进去了,下面做一个函数让链表显示一下

int link_show(linklist H){if(H->next == NULL) //如果连表是个空链表就没必要执行了printf("the link is NULL\n");linklist p;p = H;while(p->next != NULL){printf("%3d",p->next->a);p = p->next;}puts("");return 1;
}

接下来我们测试一下

int main(){linklist H;
data_t a;
H = link_creart();
while(1){scanf("%d",&a);if(a == -1){  //输入-1停止输入break;}link_insert_last(H,a);}link_show(H);
}

输入1,2,3,4,5;

1
2
3
4
51  2  3  4  5

接下来进入正题,怎样才能用交换节点的方式对单链表进行排序呢
首先需要根据位置找到节点

linklist link_inquire_pos(linklist H,int pos){int i = 0;linklist p;p = H;if(pos == -1){return NULL;}while(i<pos){i++;p = p->next;if(p == NULL){return NULL;}}return p;
}

利用上边的函数我们可以找到在链表某个位置上的节点了
接下来我们对某两个位置上的节点进行交换,函数如下所示(这个函数写的不太好请各位大神指正)

int link_exch(linklist H,int pos1,int pos2){if(H == NULL){return 0;}if(H->next == NULL || H->next->next == NULL){printf("node none or just one\n");return 0;}linklist p,q,top1,top2,r;p = link_inquire_pos(H,pos1);q = link_inquire_pos(H,pos2);if(pos1+1 != pos2){    //两个相邻节点交换位置top1 = link_inquire_pos(H,pos1-1);top2 = link_inquire_pos(H,pos2-1);top1->next = q;r = q->next;q->next = p->next;top2->next = p;p->next = r;}else{top1 = link_inquire_pos(H,pos1-1);top1->next = q;p->next = q->next;q->next = p;}return 0;
}```
求链表长度的函数```c
int link_long(linklist H){linklist p;p = H->next;if(H == NULL){return -1;}if(H->next == NULL){return 0;}int i = 0;while(p){i++;p = p->next;}return i;
}```下面我们就可以编辑排序函数啦
前边是做了一些准备编了一些函数,排序函数具体做法是:找到需要交换的节点位置,将两个节点交换(具体说明在注释中)
```c
int link_rank(linklist H){if(H == NULL){return 0;}if(H->next == NULL){  //空链表就没必要了 printf("the node is no data\n");return 0;}if(H->next->next == NULL){  //链表就一个节点(不包括头节点)也不用排序printf("the node just one data\n");return 0;}
#if 1linklist p,q;p = H->next;q = p->next;int i,j,k;k = link_long(H);i = 1;  //用i,j表示p,q指向的节点位置j = 2;while(i <= k-1){while(j <= k){if(q->a < p->a){link_exch(H,i,j);//将两个节点位置交换/*根据位置找出节点,恢复节点原来指向的位置(因为交换后p,q还指向原来的节点而这个函数是利用位置进行操作的,所以需要将p,q指向原来的位置)*/q = link_inquire_pos(H,j);p = link_inquire_pos(H,i);}j++;q = q->next;}i++;j = i+1;p = p->next;q = p->next;//将q节点指向p后的一个节点}
#else  //这个是只交换节点所存储的数据,以达到排序的目的linklist p,q;data_t i;p = H->next;q = p->next;while(p->next){while(q){if(q->a < p->a){i = q->a;q->a = p->a;p->a = i;}q = q->next;}p = p->next;q = p->next;}
#endifreturn 0;
}

我们来执行一下单链表排序

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"linktable.h"//这个是我自己写得头文件,见附件int main(){linklist H;
data_t a;
H = link_creart();
while(1){scanf("%d",&a);if(a == -1){  //输入-1停止输入break;}link_insert_last(H,a);}link_show(H);link_rank(H);link_show(H);H =   link_free(H);//释放节点所占内存return 0;
}

执行结果

我自己变得库文件
链接:https://pan.baidu.com/s/1hoIIRPrCm7w-9vMM294jyg
提取码:aiyy

菜鸟一枚,还请各位大神多多指教。

单链表排序(交换节点)相关推荐

  1. 单链表操作——交换节点

    链表是最为常见,并且经常需要使用到的数据结构之一.对于单链表的基本操作,例如创建链表.插入.删除等都不是特别复杂,但是其实对于链表的操作实际上很多的操作还是有一定的难度,例如上次给出的单链表的逆转,以 ...

  2. 单链表排序----快排 归并排序

    单链表排序----快排 & 归并排序 原文:http://blog.csdn.net/u012658346/article/details/51141288 题目描述:  给定一个乱序的单链表 ...

  3. 单链表排序之直接插入排序

    ****单链表排序之直接插入排序**** /*前段时间刚学会几种排序方法,最近学习了单链表,就用来试试,本篇链表的排序方法<一>讲述的是单链表的直接插入排序:(注意:请仔细看准节点结构体的 ...

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

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

  5. 牛客 - 单链表排序

    单链表排序 **BM12** **单链表的排序** 链接 问题描述 代码 BM12 单链表的排序 链接 单链表的排序_牛客题霸_牛客网 (nowcoder.com) 问题描述 给定一个节点数为n的无序 ...

  6. 单链表的应用--对单链表排序

      对单链表进行排序,利用前文写好的链表的框架,在链表类中补充Sort方法. 对单链表排序 一.问题分析 二.代码分析 1.链表类LinkList 2.链表方法Sort 三.测试代码 1.主函数 2. ...

  7. 面试题精选:单链表排序也能玩出花来

    今天国庆节,祝大家中秋节快乐,顺便给大家拜个早年[狗头].不过最近还在准备面试的同学们不要浪太狠,还是要好好学习的鸭. 单链表的排序在数据结构类的面试题中简直是集大成者,什么排序.链表.链表删除.添加 ...

  8. C语言版--单链表排序,冒泡排序,选择排序,插入排序,快速排序,应有尽有,保证看懂,没有bug!交换节点版本!

    一.废话不多说,直接上代码.如果想看双向循环链表的朋友,可以在我的博客里找. 你好 #include <stdio.h> #include <stdlib.h>typedef ...

  9. c语言双链表排序交换节点_图解:单链表翻转的三种方式!

    当我们在聊到链表反转的时候,一定说的都是单链表,双链表本身就具有前驱指针 Prev 和后续指针 next,无需进行翻转. 单链表反转,反转后的效果如下: 看起来很简单,只需要将单链表所有结点的 nex ...

最新文章

  1. 【C++】容器与继承
  2. python因数之和等于数字本身_python找出因数与质因数的方法
  3. QIIME 2用户文档. 16纵向和成对样本比较q2-longitudinal(2019.7)
  4. SQL Server递归查询无限级分类
  5. 十天快速入门Python
  6. HDU 5239 上海大都会 D题(线段树+数论)
  7. preempt_count详解
  8. MySQL 开发日志 -- 性能调优
  9. CodeForces - 1174D Ehab and the Expected XOR Problem(构造+思维+位运算)
  10. shell 函数定义和调用
  11. 基于Android平台的简易人脸检测库
  12. 处理mp3_如何把MP3转换成FLAC格式?这三个方法简单快速
  13. 【Oracle】ORA-01157: cannot identify/lock data file 201 - see DBWR trace file
  14. angularJs解决跨域问题-最简单的完美实例
  15. Wallpaper Engine软件——html做为壁纸
  16. 洛谷 3373 线段树
  17. Moment.js 常见用法总结
  18. 智力游戏(搬山游戏)
  19. “收藏本站” 的代码
  20. WSDM 2021 | 时间序列相关论文一览

热门文章

  1. 2022《粤语好声音-乐队风暴》全国总决赛圆满收官!
  2. acme.sh使用standalone模式流程记录及报错解决方法
  3. LS-DYNA 重启动分析
  4. 化妆品电商平台数据分析
  5. C# 中添加/删除引用,The referenced project 'xxxxxx' The referenced project
  6. AVI 视频文件的播放
  7. W7级别的服务器系统,w7系统的云服务器
  8. LINUX 降低密码复杂度,centos7 环境下修改root密码报错如下: BAD PASSWORD: it is too simplistic/systematic
  9. ubuntu搭建mqtt服务器及验证
  10. 阿里云ecs Linux软件漏洞