前言

大家在做需要排名的项目的时候,需要把各种数据从高到低排序,如果用的冒泡排序的话,处理数组是十分简单的,因为数组的存储空间的连续的,可以通过下标就可以简单的实现,但如果是链表的话,是随机分配的,不能像数组那样通过下标就直接实现。所以在这里给大家介绍一个简单一点的冒泡排序

冒泡排序

冒泡排序的是交换排序其中的一种,主要思想是每一个元素与后一个元素比较,若这个元素大于后一个元素,则交换这两个元素的位置(这里采用从小到大排序),第一次排序后最后一个数已经变成了最大数,再进行n-2次排序即可完成(假设有n个数据)。代码如下:

void BubbleSort(int a[], int n)
{for(int i = 0; i < n - 1; i++){for(int j = 0; j < n - i - 1; j++){if(a[j] > a[j + 1]){int temp = a[j];a[j] = a[j + 1];a[j + 1] = temp;}}}
}

但这只适用于连续存储空间,对于链表来说,不太适用,所以接下来我将介绍一个比较简单的代码来实现链表的冒泡排序,代码如下(该链表是包含有头结点的,即第一个结点不放数据):

void BubbleSort(NODE * &L)
{int i ,count = 0, num;//count记录链表结点的个数,num进行内层循环,NODE *p, *q, *tail;//创建三个指针,进行冒泡排序p = L;while(p->next != NULL)//计算出结点的个数{count++;//注释①p = p->next;}for(i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样{num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样,q = L->next;//令q指向第一个结点p = q->next;//令p指向后一个结点tail = L;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作while(num--)//内层循环 次数跟数组冒泡排序一样{if(q->data > p->data)//如果该结点的值大于后一个结点,则交换{q->next = p->next;p->next = q;tail->next = p;}tail = tail->next;//注释②q = tail->next;//注释②p = q->next;//注释②} }
}

注释①:
1.因为通常情况下来说,我们都不知道链表的结点个数,所以需要去计算出来做为循环的次数,如果知道的话,那也可以直接传入参数作为count。
2.为什么不直接用 p!=NULL 作为循环的次数呢,因为在交换后结点会混乱,接下来我会解释。
注释②
1.这里为什么要采用tail作为下一步操作的重要点呢,因为如果直接通过p,和q操作,很容易重复循环了,但如果通过tail进行操作的话,结点始终不会有问题
刚开始结点排序如下。

当排序完成后,进行tail = tail- >next;此时tail就是下一个结点,p和q只要按照tail的结点走,就不会出问题。
图示如下:

所以我们借用tail这个结点,就可以达到跟数组的冒泡排序一样的操作。

可运行代码:

#include<stdio.h>
#include<stdlib.h>
typedef struct node
{int data;struct node* next;
}NODE;void add(NODE* &head, int data)
{NODE *p, *L;//p 为追加的结点,L为最后一个结点p = (NODE *)malloc(sizeof(NODE));// 为p创建空间L = head;while(L->next != NULL)//当L-next == NULL的时候,就代表是L是最后一个结点{L = L->next;}p->data = data;//把值赋给p中的data域p->next = NULL;L->next = p;//把新创建的结点加入到当前链表中
}void BubbleSort(NODE* &L)
{int i ,count = 0, num;//count记录链表结点的个数,num进行内层循环,NODE *p, *q, *tail;//创建三个指针,进行冒泡排序p = L;while(p->next != NULL)//计算出结点的个数{count++;//注释①p = p->next;}for(i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样{num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样,q = L->next;//令q指向第一个结点p = q->next;//令p指向后一个结点tail = L;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作while(num--)//内层循环 次数跟数组冒泡排序一样{if(q->data > p->data)//如果该结点的值大于后一个结点,则交换{q->next = p->next;p->next = q;tail->next = p;}tail = tail->next;//注释②q = tail->next;//注释②p = q->next;//注释②}}
}int main()
{NODE *head = (NODE *)malloc(sizeof(NODE));//定义头结点head->next = NULL;int n;//输入链表的长度printf("请输入链表的长度: ");scanf("%d", &n);printf("请输入链表中的数字: ");for(int i = 0; i < n; i++){int x;//每一个结点输入的值scanf("%d", &x);add(head, x);//向链表追加当前结点}BubbleSort(head);//进行冒泡排序NODE *p = head->next;//因为第一个结点没有存放数据,所以从第二个结点开始输出while(p != NULL){printf("%d\t", p->data);p = p->next;}return 0;
}

如果有疑问和见解,欢迎大家提出来一起分享。(新手作文,写的不太明白,见谅见谅~)

**

温馨提示:第一个结点不是用来放数据的,是用来辅助完成排序的。

**

单链表的冒泡排序(简单易懂)相关推荐

  1. java实现链表冒泡排序_单链表的冒泡排序

    起因 今天利用空余时间在九度做ACM的时候,需要对单链表进行排序,由于单链表不是随机存取结构,所以我不建议用快速排序,因此采用了冒泡排序! 带头节点的尾插法构建单链表 //初始化带头节点的链表 str ...

  2. 单链表的Java简单实现

    最近在研究单链表相交的问题时,为验证思路的正确性,使用java简单实现了单链表,包括增删改查和判断是否有环及解环.成环等方法. public class Node {private int value ...

  3. 统计单词数,题解简单易懂量少

    题目描述 一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数. 现在,请你编程实现这一功能,具体要求是:给定一个单词,请你输出它在给 ...

  4. C语言 | 单链表的冒泡排序

    直接上代码: #include <stdio.h> #include <stdlib.h>struct node {int data;struct node *next; }; ...

  5. 冒泡排序算法的单链表实现

    引言: 这几天都在忙着参加几个工作室(别问为什么是"几个",问就是海投)的考核,报的都是后台组.后台的考核中必定是少不了单链表ADT和排序算法的.本专栏将专攻排序算法部分.注意,是 ...

  6. 单链表的简单操作与演示

    单链表的简单操作与演示 单链表 单链表概念和简单的设计 单链表是一种链式存取的数据结构,链表中的数据是以结点来表示的,每个结点由元素和指针构成. 元素表示数据元素的映象,就是存储数据的存储单元:指针指 ...

  7. 数据结构单链表的创建以及简单操作

    在数据结构中: 目录 一.数据节点类型结构体封装 二.创建单链表 1.创建链表 2.头部插入 3.遍历链表 4.尾部插入 5.释放链表 链表可以解决顺序表无法开辟连续空间的问题,大大提高了内存的利用率 ...

  8. 数据结构(三)之单链表反向查找

    一.反向查找单链表 1.简单查找 先遍历获取单链表单长度n,然后通过计算得到倒数第k个元素的下标为n-k,然后查找下标为n-k的元素. 2.优化查找 先找到下标为k的元素为记录点p1,然后设置新的记录 ...

  9. 数据结构之线性表-链式存储之单链表(一)

    本人文笔较差,语文从来不及格,基础不好,写此类文章仅供自己学习,理解队列及其他知识,高手大神请略过.参考书籍 <数据结构与算法分析-Java语言描述> 1.1 单链表简介 线性表的最大的缺 ...

最新文章

  1. 尺取法 || emmmm
  2. sql语句性能优化【转载】
  3. java ssl证书生成_java – 使用jdk中提供的keytool生成SSL证书
  4. Python并发与并行的新手指南
  5. SAP GUI是如何启动本地安装的office word应用的
  6. 清除dns缓存命令行_怎么防止移动dns劫持,防止移动dns劫持要先了解什么是dns劫持...
  7. Cisco路由器故障诊断技术(3)
  8. .net的label的背景如何设置成为透明_css如何设置背景图片?background属性添加背景图片...
  9. Spring基于Annotation实现事务管理
  10. 【Linux】kali 2019.4 安装中文输入法
  11. centos7本地安装mysql数据库_在CentOS7系统上安装MySQL数据库
  12. 应用程序分别从SSRS2005和SSRS2008获取报表列表的方法差异
  13. 正则表达式:模式修饰符(自用)
  14. netbeans写登录界面java_NetBeans 界面美化与字体设置
  15. 最大流问题(超详细!!!)
  16. C语言中的运算符大全(内附优先级表)
  17. SharePoint Designer 2010 简介 - SharePoint Designer - Office.com
  18. DVWA-Writeup
  19. Android录制微信小视频
  20. 自动驾驶下的伦理困境

热门文章

  1. golang mysql 中间件_golang编写的数据库中间件kingshard
  2. Android 实现 IOS相机滑动控件
  3. 戴尔服务器虚拟机配置ip地址,虚拟机下CentOS配置IP地址的三种方法
  4. 时间戳Long转int变为负数
  5. 5.15 系统预设渐变库的使用 [Illustrator CC教程]
  6. JVM垃圾回收器之Shenandoah收集器
  7. c语言课程设计情侣,C/C++编程笔记:C语言制作情侣必备《爱情电子相册》,源码解析!...
  8. vs2015配置python_安装 VS2017 并卸载 VS2015 之后 Python 出现严重兼容性问题
  9. 【万里征程——Windows App开发】文件数据——文件选取器
  10. 『SignalR』.NET使用 SignalR 进行实时通信初体验