1.问题来源

在刷题是遇到字符串相关问题中使用 strcmp()函数。

在函数比较过程中有使用 排序函数 Sort(beg,end,comp),其中comp这一项理解不是很彻底。

#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<const char*> cats {"Heathcliff", "Snagglepuss", "Hobbes", "Garfield"};
std::sort(cats.begin(), cats.end(), [](const char *strA, const char *strB) { return std::strcmp(strA, strB) < 0; }); // 注意这个comp的写法
for (const char *cat : cats) {
std::cout << cat << '\n';
}
}
/*
*输出:
*Garfield
Heathcliff
Hobbes
Snagglepuss
*/
/*
* [](const char *strA, const char *strB) { return std::strcmp(strA, strB) < 0; } 不是很理解 ,为什么在前面还需要 [] 来实现?
*/

当然也可以定义一个comp变量函数

std::sort(begin(),end(),compare);
bool compare (const char* strA,const char* strB )
{
return std::strcmp(strA,strB)<0;
}

2.comp的定义

Elements are compared using the given binary comparison function comp.

这一块的内容还是需要继续学习

3.各种排序算法的实现

排序算法列表:

0.Bubble Sort 冒泡排序

1.Selection Sort 选择排序

2.Insertion Sort 插入排序

3.Shell Sort 希尔排序

4.Merge Sort 归并排序

5.Heap Sort 堆排序

6.Quick Sort 快速排序

0.BubbleSort

  • 冒泡排序实现,两两比较关键字
// 基础实现
void BubbleSort(vector<int>& nums){
int i,j;
int len=nums.size();
for(i=0;i<len;++i){
// 后面向前进行循环
// 最小值冒泡到顶端
for(j=len-2;j>=i;--j){
if(nums[j]>nums[j+1])
{
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
}
}
}
} // 改进版本
void BubbleSort2(vector<int>& nums){
int i,j;
int len=nums.size();
bool flag=true;
for(i=0;i<len &&flag;i++){
flag=false;
for(j=len-2;j>=i;--j){
if(nums[j]>nums[j+1]){
// 有数据交换
int temp=nums[j];
nums[j]=nums[j+1];
nums[j+1]=temp;
flag=true;
}
}
}
}

1.Selection Sort

  • 选择排序的基本思路:

在未排序的数组中找到最小的元素与未排序数组的第一个元素进行交换

void SelectionSort(vector<int>& nums)
{
for(int i=0;i<nums.size();++i)
{
int min_index=i;
for(int j=i+1;j<nums.size();++j) // 遍历维排序数组
{
if(nums[j]<nums[min_index])
min_index=j; // 找到最小的元素的下标
}
int temp=nums[i]; // 交换
nums[i]=nums[min_index];
nums[min_index]=temp;
}
}
/*
* 时间复杂度: O(n^2) 空间复杂度 : O(1)
* in_palce order ?
*/

2.InsertionSort

  • 插入排序的基本思路:

与要插入的元素之前的元素进行对比,元素要不断的向右进行移动

void InsertionSort(vector<int>& nums)
{
for(int i=1;i<nums.size();++i)
{
int temp=a[i]; // 要插入的元素
int j=i-1;
while(j>=0 && temp<a[j]) // 之前的元素相对比,向右移动
{
a[j+1]=a[j];
j--;
}
a[j+1]=temp;
}
}
/*
* 时间复杂度 O(n^2)
*/

同样的解题思路,java代码看着更舒服

public class Insertion
{
public static void sort(Comparable[] a)
{
// ascending
int N=a.length;
for(int i=1;i<N;i++)
{
// 将 a[i]插入到 a[i-1],a[i-2]中
for(int j=i;j>0 && less(a[j],a[j-1]);j--)
{
exch(a,j,j-1);
}
}
} }

3.ShellSort

希尔排序的主要思路:

希尔排序是基于插入排序的快速排序

1.交换不相邻的元素对数组的局部进行排序(最重要的就是间隔的选择)

2.最终使用插入排序将局部有序的数组排序

/* 至今无法解释其算法性能
* 这个算法熟悉知道一下就好
*/
public class Shell
{
public static void sort(Comparable[] a)
{
int N=a.length();
int h=1; // 定义这个间隔 gap
while(h<N/3)
h=h*3+1;
while(h>=1)
{
for(int i=h;i<N;i++)
{
for(int j=i;j>0 && less(a[j],a[j-h]);j-=h)
exch(a,j,j-h);
}
h=h/3; // 缩小gap继续进行交换
}
}
}

Cplusplus implemented

void ShellSort(int a[],int len)
{
for(int gap=len/2;gap>0;gap/=2)
{
for(int i=gap;i<len;i++)
{
int j=i-gap;
while(j>=0 && a[j]>a[j+gap])
{
swap(a[j],a[j+gap]);
j-=gap;
}
}
}
}

4.MergeSort

归并排序的主要思路:

现将数组递归的分成两半分别排序,再将结果归并起来

将数组递归的分成最小,按照有序的方式归并起来

/*
* 所需的时间复杂度O(NlogN)
*/
// 两个数组的原地归并 public class Merge
{
private static Comparable[] aux;
public static void sort(Comparable[] a)
{
aux=new Comparable[a.length]; // 分配空间
sort(a,0,a.length-1);
}
private static void sort(Comparable[] a,int lo,int hi) // a[lo,hi]进行排序
{
if(hi<lo)
return;
int mid=lo+(hi-lo)/2;
sort(a,lo,mid);
sort(a,mid+1,hi);
merge(a,lo,mid,hi);
}
public static void merge(Comparable[]a,int lo,int mid,int hi)
{
int i=lo,j=mid+1;
for(int k=lo;k<hi;++k)
aux[k]=a[k]; // 将数组完全复制到一个临时数组中
for(int k=lo;k<=hi;k++)
{
if(i>mid) a[k]=aux[j++]; // 分别对应左半数组和右半数组用尽的情况
else if (j>hi) a[k]=aux[i++];
else if (less(a[i],a[j])) a[k]=aux[i++];
else a[k]=aux[j++];
}
}
}

5.HeapSort

堆排序

  • 经典而又优雅的排序算法

堆排序思路:

基于(二叉堆的数据结构)优先队列实现,优先队列是利用二叉堆来实现的。

1.根据堆的构造,现将堆构造出来

2.根据 sink 算法实现堆的下沉排序 最后实现有序

sink 算法,将堆有序的最后一个元素交换到顶点,从顶点开始下沉操作

// 堆的有序化
private void swim (int k)
{
while(k>1 && less(k/2,k))
{
exch(k/2,k);
k=k/2;
}
}
private void sink(int k)
{
while(2*k<=N) // 保证还有字节点可以下沉比较
{
int j=2*k;
if(j<N && less(j,j+1)) j++; // 找到字节点中最大的进行交换
if(!less(k,j)) break;
exch(k,j);
k=j;
}
} public class Heap { // This class should not be instantiated.
private Heap() { } /**
* Rearranges the array in ascending order, using the natural order.
*/
public static void sort(Comparable[] pq) {
int n = pq.length;
for (int k = n/2; k >= 1; k--)
sink(pq, k, n); // 第一步实现堆的有序 2N项比较
while (n > 1) { // 2NlgN次比较
exch(pq, 1, n--); // 交换顶点和尾结点的元素
sink(pq, 1, n); // 进行下沉
}
} /***************************************************************************
* Helper functions to restore the heap invariant.
***************************************************************************/ private static void sink(Comparable[] pq, int k, int n) {
while (2*k <= n) {
int j = 2*k;
if (j < n && less(pq, j, j+1)) j++;
if (!less(pq, k, j)) break;
exch(pq, k, j);
k = j;
}
}
}

6.QuickSort

快速排序的思路:

最重要的是找到切分元素,将数组分成左右两个部分 (切分元素的选取)

切分后进行双指针比较,根据与切分元素的比较,将元素进行交换位置

将左右两个部分进行排序

/*
* 快速排序是原地排序
* 分而治之的排序方法
* 时间复杂度 O(NlgN)
*/ public class Quick
{
public static void sort(Comparable[] a)
{
StdRandom.shuffle(a); // 重新打乱混淆一下数组,这样对切分元素的选择更理想
sort(a,0,a.length-1);
}
private static void sort(Comparable[]a,int lo,int hi)
{
if(hi<=lo) // 进行错误判断
return;
int j=partition(a,lo,hi); // get 切分元素
sort(a,lo,j-1); // 左右两边数组进行排序
sort(a,j+1,hi);
}
/* 切分的实现*/
private static int partition(Comparable[]a ,int lo,int hi)
{
// 将数组进行分离 a[lo,...i-1] a[i+1...hi]
int i=lo,j=hi+1;
Comparable v=a[lo]; // 确定切分元素
while(true)
{
while(less(a[++i],v)) if(i==hi) break; // 到不小于V,应该在右侧的元素
while(less(v,a[--j])) if(j==lo) break; // 小于 V,应该在左侧的元素
if(i>=j) break;
exch(a,i,j);
}
exch(a,lo,j); // 将v 放入正确的位置,切分值放到a[j]中
/* a[lo,..j-1]<=a[j]<=a[j+1..hi] */
return j;
}
}

选择排序、快速排序、归并排序、堆排序、快速排序实现及Sort()函数使用的更多相关文章

  1. php基础排序算法 冒泡排序 选择排序 插入排序 归并排序 快速排序

    <?php$arr=array(12,25,56,1,75,13,58,99,22);//冒泡排序function sortnum($arr){    $num=count($arr);    ...

  2. 几种常见排序算法之Java实现(插入排序、希尔排序、冒泡排序、快速排序、选择排序、归并排序)

    排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个关键字有序的序列. 稳定度(稳定性)一个排序算法是稳定的,就是当有两个相等记录的关 ...

  3. Java冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序

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

  4. java实现冒泡排序,选择排序,插入排序,快速排序(简洁版)及性能测试

    1.冒泡排序是排序里面最简单的了,但性能也最差,数量小的时候还可以,数量一多,是非常慢的. 它的时间复杂度是O(n*n),空间复杂度是O(1) 代码如下,很好理解. public void bubbl ...

  5. Java选择排序,插入排序,快速排序

      public class Test { public static void main(String[] args) { int a[] = { 1, 2, 3, 4, 5 }; 选择排序(a); ...

  6. 排序方法整理Java - 冒泡排序、选择排序、插入排序、快速排序

    /** * 排序方法整理 * @author zhyea * */ public class Sort { /** * 冒泡排序,从小到大. * 冒泡排序是比较相邻的两个元素,若顺序错误,则执行交换. ...

  7. 常见排序算法总结分析之选择排序与归并排序-C#实现

    本篇文章对选择排序中的简单选择排序与堆排序,以及常用的归并排序做一个总结分析. 常见排序算法总结分析之交换排序与插入排序-C#实现是排序算法总结系列的首篇文章,包含了一些概念的介绍以及交换排序(冒泡与 ...

  8. C++/C实现各种排序算法(持续更新)--冒泡排序,选择排序,归并排序

    2018 3 17 今日总结一下C++中的排序算法: 1冒泡排序 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是 ...

  9. c语言 快速排序---归并排序----堆排序

    //快速排序: #include <stdio.h> #define MAX 500000 int s[MAX]; void Q_Sort(int start,int end) { int ...

  10. 冒泡(bubblesort)、选择排序、插入排序、快速排序

    冒泡排序(bubblesort) 特点:通过换位置的方式,一直向上冒泡 package main import "fmt" func bubbleSortAsc(arrayA [] ...

随机推荐

  1. 解决axios接收二进制流文件乱码问题

    1. 须将axios 配置中的responseType设置为'arraybuffer',这样就不会让表格出现乱码现象: 2. 如果要动态设置文件名则需要让后台将名字设置到响应头中,否则将是一个乱码的文 ...

  2. JS面向对象编程(二):构造函数的继承

    对象之间继承的 5 中方法.            比如, 现在有一个"动物"对象的构造函数.            function Animal(){              ...

  3. rocksdb编译步骤——Java、Golang、mac

    如果不是必要不建议自己编译rocksdb,编译的过程比较耗时费力.现在已经有很多编译好的文件可供使用. Java <!-- https://mvnrepository.com/artifact/ ...

  4. 使用Minifly打造基于视觉感知的跟踪无人机

    前言:无人机和人工智能现在是非常热门的话题,将两者结合起来是一个比较好的创意,本文介绍一种可行的解决方案来实现基于视觉感知的跟踪无人机.从零开始搭建无人机系统工作量和难度(以及钱)都是非常大的,所以在 ...

  5. Hadoop 系列(三)—— 分布式计算框架 MapReduce

    一.MapReduce概述 Hadoop MapReduce 是一个分布式计算框架,用于编写批处理应用程序.编写好的程序可以提交到 Hadoop 集群上用于并行处理大规模的数据集. MapReduce ...

  6. 理解nodejs中的stream(流)

    阅读目录 一:nodeJS中的stream(流)的概念及作用? 二:fs.createReadStream() 可读流 三:fs.createWriteStream() 可写流 回到顶部 一:node ...

  7. 使用 PowerShell 远程管理

    要求 PowerShell 版本要求至少是2.0版本以上,目前PowerShell 2.0 支持最低的操作系统版本为Windows XP.本次操作使用的是 PowerShell 5.1 请使用管理员身 ...

  8. php sql 类似 mybatis 传参

    PHP sql 处理上,没有类似于 java mybatis 的工具,导致进行一些sql 处理时,会有诸多不便, 楼主抽时间写了一个 php 类似 mybatis 的sql 工具,省去了拼装sql 的 ...

  9. Spring Boot 2.X 如何快速整合jpa?

    本文目录 一.JPA介绍二.Spring Data JPA类结构图1.类的结构关系图三.代码实现1.添加对应的Starter2.添加连接数据库的配置3.主要代码 一.JPA介绍 JPA是Java Pe ...

  10. ASP.NET CORE 2.* 利用集成测试框架覆盖HttpClient相关代码

    ASP.NET CORE 集成测试官方介绍 我的asp.net core 项目里面大部分功能都是去调用别人的API ,大量使用HttpClient,公司单元测试覆盖率要求95%以上,很难做到不mock ...