热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

几种经典排序算法的R语言描述

1.数据准备#测试数组vectorc(5,34,65,36,67,3,6,43,69,59,25,785,10,11,14)vector##[1]53465366736436959
1.数据准备
# 测试数组
vector = c(5,34,65,36,67,3,6,43,69,59,25,785,10,11,14)
vector

##  [1]   5  34  65  36  67   3   6  43  69  59  25 785  10  11  14
2.R语言内置排序函数

在R中和排序相关的函数主要有三个:sort(),rank(),order()。

  • sort(x)是对向量x进行排序,返回值排序后的数值向量;
  • rank()是求秩的函数,它的返回值是这个向量中对应元素的“排名”;
  • order()的返回值是对应“排名”的元素所在向量中的位置。
sort(vector)
##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
order(vector)
##  [1]  6  1  7 13 14 15 11  2  4  8 10  3  5  9 12
rank(vector)
##  [1]  2  8 12  9 13  1  3 10 14 11  7 15  4  5  6
 3.冒泡排序

冒泡排序是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

# bubble sort
bubbleSort = function(vector) {
  n = length(vector)
  for (i in 1:(n-1)) {
    for (j in (i+1):n) {
      if(vector[i]>=vector[j]){
        temp = vector[i]
        vector[i] = vector[j]
        vector[j] = temp
        }
      }
    }
  return(vector)
}
bubbleSort(vector)

##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
4.快速排序

基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

# quick sort
quickSort = function(vector, small, big) {
  left = small
  right = big
  if (left >= right) {
    return(vector)
  }else{
    markValue = vector[left]
    while (left < right) {
      while (left = markValue) {
        right = right - 1
      }
      vector[left] = vector[right]
      while (left  markValue) {
        left = left + 1
      }
      vector[right] = vector[left]
    }
  vector[left] = markValue
  vector = quickSort(vector, small, left - 1)
  vector = quickSort(vector, right + 1, big)
  return(vector)
  }
}
quickSort(vector,1,15)

##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
5 插入排序

有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素)。在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中。插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。

# insert sort
insertSort = function(vector){
  n = length(vector)
  for(i in 2:n){
    markValue = vector[i]
    j=i-1
    while(j>0){
      if(vector[j]>markValue){
        vector[j+1] = vector[j]
        vector[j] = markValue
      }
      j=j-1
    }
  }
  return(vector)
}
insertSort(vector)

##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
6.希尔排序

希尔排序是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

# shell sort
shellSort = function(vector){
   n = length(vector)
   separate = floor(n/2)
   while(separate>0){
     for(i in 1:separate){
       j = i+separate
       while(j<=n){
         m= j- separate
         markVlaue = vector[j]
         while(m>0){
           if(vector[m]>markVlaue){
             vector[m+separate] = vector[m]
             vector[m] = markVlaue
           }
           m = m-separate
         }
         j = j+separate
       }
     }
     separate = floor(separate/2)
   }
   return(vector)
}
shellSort(vector)

##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
7.选择排序

选择排序是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。选择排序是不稳定的排序方法.

# select sort
selectSort = function(vector){
  n = length(vector)
  for(i in 1:(n-1)){
    minIndex = i
    for(j in (i+1):n){
      if(vector[minIndex]>vector[j]){
        minIndex = j
      }
    }
    temp = vector[i]
    vector[i] = vector[minIndex]
    vector[minIndex] = temp
  }
  return(vector)
}
selectSort(vector)

##  [1]   3   5   6  10  11  14  25  34  36  43  59  65  67  69 785
8.堆排序

堆排序是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

# heap sort
adjustHeap = function(vector,k,n){
  left = 2*k
  right = 2*k+1
  max = k
  if(k<=n/2){
    if(left<=n&&vector[left]>=vector[max]){
      max = left
    }
    if(right<=n&&vector[right]>=vector[max]){
      max = right
    }
    if(max!=k){
      temp = vector[k]
      vector[k] = vector[max]
      vector[max] = temp
      vector = adjustHeap(vector,max,n)
    }
  }
  return(vector)
}
createHeap = function(vector,n){
  for(i in (n/2):1){
    vector = adjustHeap(vector,i,n)
  }
  return(vector)
}
heapSort = function(vector){
  n = length(vector)
  vector = createHeap(vector,n)
  for(i in 1:n){
    temp = vector[n-i+1]
    vector[n-i+1] = vector[1]
    vector[1] = temp
    vector = adjustHeap(vector,1,n-i)
  }
  return(vector)
}
9.归并排序

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

# merge sort
combine = function(leftSet,rightSet){
  m = 1
  n = 1
  vectorTemp = c()
  while (m<=length(leftSet)&&n<=length(rightSet)) {
    if(leftSet[m]<=rightSet[n]){
      vectorTemp = append(vectorTemp,leftSet[m])
      m = m+1
    }else{
      vectorTemp = append(vectorTemp,rightSet[n])
      n = n+1
    }
  }
  if(m>length(leftSet)&&n==length(rightSet)){
    vectorTemp = append(vectorTemp,rightSet[n:length(rightSet)])
  }else if(m==length(leftSet)&&n>length(rightSet)){
    vectorTemp = append(vectorTemp,leftSet[m:length(leftSet)])
  }
  return(vectorTemp)
}
mergeSort = function(vector){
  size = length(vector)
  if(size==1){
    return(vector)
  }
    cut = ceiling(size/2)
    leftSet = mergeSort(vector[1:cut])
    rightSet = mergeSort(vector[(cut+1):size])
    vector = combine(leftSet,rightSet)
    return(vector)
}

本文链接:http://www.cnblogs.com/homewch/p/5927280.html

几种经典排序算法的R语言描述


推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解Cookie与Session会话管理
    本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
  • 本文探讨了如何通过最小生成树(MST)来计算严格次小生成树。在处理过程中,需特别注意所有边权重相等的情况,以避免错误。我们首先构建最小生成树,然后枚举每条非树边,检查其是否能形成更优的次小生成树。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • 本文介绍了如何使用jQuery根据元素的类型(如复选框)和标签名(如段落)来获取DOM对象。这有助于更高效地操作网页中的特定元素。 ... [详细]
  • 本文介绍如何在 Xcode 中使用快捷键和菜单命令对多行代码进行缩进,包括右缩进和左缩进的具体操作方法。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
author-avatar
豆芽哥的马甲_206
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有