目录

  • 算法思想
  • 代码实现
    • 头插法递增
    • 头插法递减
    • 尾插法递增
    • 尾插法递减
  • 完整程序测试
  • 测试结果

算法思想

我们用不带头结点的单链表实现简单选择排序。
递增:每次从原链表中找出一个最大(最小)元素,然后头插(尾插)到结果链表中。
递减:每次从原链表中找出一个最小(最大)元素,然后头插(尾插)到结果链表中。

代码实现

头插法递增

//单链表实现简单选择排序(递增)
void SelectSort(LinkList &L){//此方法采用不带头结点的头插法LNode *h = L,*p,*q,*r,*s;//h指针指向原链表L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最大结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最大结点sif (p->data > s->data) {//若找到最大结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最大结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最大结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是头插法的步骤s->next = L;L = s;}
}

头插法递减

只需要把头插法递增代码中的if (p->data > s->data)改为if (p->data < s->data)即可。

//单链表实现简单选择排序(递减)
void SelectSort2(LinkList &L){//此方法采用不带头结点的头插法LNode *h = L,*p,*q,*r,*s;//h指针指向原链表L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最小结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最小结点sif (p->data < s->data) {//若找到最小结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最小结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最小结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是头插法的步骤s->next = L;L = s;}
}

尾插法递增

//单链表实现简单选择排序(递增)
void SelectSort3(LinkList &L){//此方法采用不带头结点的尾插法LNode *h = L,*p,*q,*r,*s,*t = L;//h指针指向原链表,t为结果链表尾指针L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最小结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最小结点sif (p->data < s->data) {//若找到最小结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最小结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最小结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是尾插法的步骤if(L == NULL){//插入第一个结点时需要特殊处理L = s;t = s;}else{t -> next = s;t = s;//t指向新的表尾结点}}t -> next = NULL;//尾结点指针置空
}

尾插法递减

同样,只需要把尾插法递增中的if (p->data < s->data)改为p->data > s->data即可。

//单链表实现简单选择排序(递减)
void SelectSort4(LinkList &L){//此方法采用不带头结点的尾插法LNode *h = L,*p,*q,*r,*s,*t = L;//h指针指向原链表,t为结果链表尾指针L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最大结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最大结点sif (p->data > s->data) {//若找到最大结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最大结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最大结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是尾插法的步骤if(L == NULL){//插入第一个结点时需要特殊处理L = s;t = s;}else{t -> next = s;t = s;//t指向新的表尾结点}}t -> next = NULL;//尾结点指针置空
}

完整程序测试

#include<iostream>
using namespace std;
#include<stdlib.h>
typedef int ElemType;
typedef struct LNode{//定义单链表结点类型ElemType data;//数据域struct LNode *next;//指针域
}LNode,*LinkList;//单链表打印输出
void LinkListPrint(LinkList L){LNode *p = L;while(p != NULL){printf("%d ",p -> data);//遍历输出单链表中元素值p = p -> next;}printf("\n");
}//头插法建立单链表(不带头结点)
LinkList List_HeadInsert(LinkList &L){L = NULL;//不带头结点的单链表初始化指向NULLLNode *s;//待插入的新结点int x;//待插入的新结点的元素值scanf("%d",&x);//输入新结点的值while(x != 9999) {//当x等于9999时插入停止s = (LNode *) malloc(sizeof(LNode));//创建新结点s->data = x;//新结点赋值s->next = L;L = s;//将新结点插入表中,L始终指向新插入的结点scanf("%d", &x);}
}//尾插法建立单链表(不带头结点)
LinkList List_TailInsert(LinkList &L){L = NULL;//初始化单链表,头指针L指向NULLLNode *s;//待插入新结点LNode *r = L;//r为表尾指针int x;//待插入新结点元素值scanf("%d",&x);//输入新结点while(x != 9999){//输入9999表示插入结束s = (LNode *)malloc(sizeof(LNode));//创建新结点s -> data = x;//新结点赋值if(L == NULL){//插入第一个结点时需要特殊处理L = s;r = s;}else{r -> next = s;r = s;//r指向新的表尾结点}scanf("%d",&x);}r -> next = NULL;//尾结点指针置空
}//单链表实现简单选择排序(递增)
void SelectSort(LinkList &L){//此方法采用不带头结点的头插法LNode *h = L,*p,*q,*r,*s;//h指针指向原链表L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最大结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最大结点sif (p->data > s->data) {//若找到最大结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最大结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最大结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是头插法的步骤s->next = L;L = s;}
}//单链表实现简单选择排序(递减)
void SelectSort2(LinkList &L){//此方法采用不带头结点的头插法LNode *h = L,*p,*q,*r,*s;//h指针指向原链表L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最小结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最小结点sif (p->data < s->data) {//若找到最小结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最小结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最小结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是头插法的步骤s->next = L;L = s;}
}//单链表实现简单选择排序(递增)
void SelectSort3(LinkList &L){//此方法采用不带头结点的尾插法LNode *h = L,*p,*q,*r,*s,*t = L;//h指针指向原链表,t为结果链表尾指针L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最小结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最小结点sif (p->data < s->data) {//若找到最小结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最小结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最小结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是尾插法的步骤if(L == NULL){//插入第一个结点时需要特殊处理L = s;t = s;}else{t -> next = s;t = s;//t指向新的表尾结点}}t -> next = NULL;//尾结点指针置空
}//单链表实现简单选择排序(递减)
void SelectSort4(LinkList &L){//此方法采用不带头结点的尾插法LNode *h = L,*p,*q,*r,*s,*t = L;//h指针指向原链表,t为结果链表尾指针L = NULL;//L为结果链表while(h != NULL) {//原链表不能为空p = s = h;//p为工作指针,s指向最大结点,每一趟都指向原链表的表头的第一个结点q = r = NULL;//q为p的前驱,r为s的前驱while (p != NULL) {//扫描原链表,寻找最大结点sif (p->data > s->data) {//若找到最大结点,则用s记录,r记录其前驱结点s = p;r = q;}q = p;//未找到,继续寻找p = p->next;}if (s == h) {//若最大结点在链表的第一个结点位置h = h->next;//也即让s加入结果链表,h指针后移,下一趟不再考虑这一趟的s} else {//若最大结点在链表的表内r->next = s->next;//也即在s加入到结果链表之前,让其前驱r的next指针指向s的下一个结点,防止断链}//以下是尾插法的步骤if(L == NULL){//插入第一个结点时需要特殊处理L = s;t = s;}else{t -> next = s;t = s;//t指向新的表尾结点}}t -> next = NULL;//尾结点指针置空
}int main(){LinkList L;
//    List_HeadInsert(L);List_TailInsert(L);printf("排序前:");LinkListPrint(L);
//    SelectSort(L);
//    SelectSort2(L);
//    SelectSort3(L);SelectSort4(L);printf("排序后:");LinkListPrint(L);return 0;
}

测试结果

单链表实现简单选择排序相关推荐

  1. 2015年数据结构第四题(带头结点单链表的简单选择排序)(C/C++)

    题目: 算法思想:每次从单链表的待排序部分中找到最小的元素所在的节点,再和与头节点直接相连的单链表的已排序部分的下一个结点通过调整指针的方式交换位置,重复多次即可. 代码实现: #include< ...

  2. 单链表的简单选择排序

    LinkList selectsort(LinkList &L) {LNode *p=L->next,*q,*min;while(p){q=p->next;min=p;while( ...

  3. 【链表】简单选择排序

    题目描述: 编写一个算法,在基于单链表表示的待排序关键字序列上进行简单选择排序. 算法思想: 每趟在原始链表中摘下关键字最大的结点,把它插入到结果链表的最前端,由于在原始链表中摘下的关键字越来越小,在 ...

  4. 4022-基于链表的简单选择排序(C++,附思路)

    描述 试以单链表为存储结构,实现简单选择排序算法. 输入 多组数据,每组数据两行.第一行为序列的长度n,第二行为序列的n个元素(元素之间用空格分隔,元素都为正整数).当n等于0时,输入结束. 输出 每 ...

  5. 基于链表的简单选择排序

    描述 试以单链表为存储结构,实现简单选择排序算法. 输入 多组数据,每组数据两行.第一行为序列的长度n,第二行为序列的n个元素(元素之间用空格分隔,元素都为正整数).当n等于0时,输入结束. 输出 每 ...

  6. 数据结构(八):排序 | 插入排序 | 希尔排序 | 冒泡排序 | 快速排序 | 简单选择排序 | 堆排序 | 归并排序 | 基数排序 | 外部排序 | 败者树 | 置换-选择排序 | 最佳归并树

    文章目录 第八章 排序 一.排序的基本概念 (一)什么是排序 (二)排序的应用 (三)排序算法的评价指标 (四)排序算法的分类 (五)总结 二.插入排序 (一)算法思想 (二)算法实现 (三)算法效率 ...

  7. C语言——十四种内部排序算法【直接插入排序-冒泡排序-选择排序-插入排序-希尔排序-归并排序-快速排序-堆排序-折半插入排序-二分查找-路插入排序-表插入排序-简单选择排序-直接选择排序-树形选择】

    目录: 一:插入排序 A:直接插入排序 1.定义: 2.算法演示 实例1: 3.基本思想 4.排序流程图 实例1: B:希尔排序 1.定义: 2.算法演示 实例2: C:其他插入排序 a:折半插入排序 ...

  8. 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

  9. 单链表的建立、排序和翻转

    链表: 1.注意是否有带头结点. 2.单链表的建立:顺序建表(尾插法).逆序建表(头插法). 3.单链表的插入.删除操作需要寻找前驱结点. 单链表的建立.排序和翻转,都是针对有头结点的单链表. #in ...

最新文章

  1. 计算机存储技术及其发展了论文,计算机网络存储技术探究-计算机网络论文-计算机论文(13页)-原创力文档...
  2. vue中获取url参数
  3. Struts2之环境配置
  4. Android 地图搜索商家,检索关键字(高德地图,百度地图),地址搜索
  5. linux h5 动画软件下载,技术|7款绚丽的jQuery/HTML5动画及源码
  6. Struts 2框架创建的第一个项目
  7. 蓝牙扫描_无线扫描枪常见的传输模式及其区别
  8. 一种被国人漠视的精神---狼的精神
  9. DOM方式解析XML文件实例
  10. php编写 密码检查,php-检查旧密码和新密码的规则
  11. 《FDTD electromagnetic field using MATLAB》读书笔记之一阶、二阶偏导数差商近似
  12. SQL数据导入mongodb
  13. python三维转换教程_Python科学计算三维可视化【完结】
  14. python任务编排_工作流中的任务编排与治理
  15. DbVisualizer 解决注释中文乱码问题
  16. 大于3小于4的整数bleem_六年级数学小升初知识点梳理
  17. 日常坚持记账,简单好用的记账本分享给你
  18. javaJDK64位下载
  19. window.onload的用法
  20. Swift使用UIImagePickerController 从相册选择图片、从相机选择图片

热门文章

  1. owncloud 实现私有云进行多端文件同步
  2. HCIA总结DAY4
  3. ABAP-SUBMIT传值(基本)
  4. Css3动画浏览器兼容问题
  5. 稼说送张琥 ---博观而约取
  6. 2015-2016年Unity项目经历
  7. android面试(16)-数据库存储框架greendao
  8. arduino数字时钟元件_数字元器件基础
  9. Java基础学习——第六章 面向对象编程(下)
  10. 打造你的IT技能大厦---谈一谈学习方法