今天看剑指offer突然发现下学期都要去面试了,还没自己实现过快排非递归和归并非递归,这怎么能行呢,于是就写了一下。

(虽然有点卡壳,又回去翻了下算导,还是顺利写出来了)

先放图: 一亿数据量:

#pragma warning(disable:4996)
#include <iostream>
#include <string>
#include <cctype>
#include<vector>
#include<list>
#include<cstring>
#include<typeinfo>
#include<set>
#include<map>
#include<deque>
#include<regex>
#include<sstream>
#include<cstdlib>
#include<queue>
#include<stdlib.h>
#include<stdio.h>
#include<stack>
#include<algorithm>
#include<thread>
#include<mutex>
#include<assert.h>
using namespace std;
void MergeSort(vector<int>& nums)
{
if (nums.empty())
{
return;
}
int len = nums.size();
vector<int> temp(len, 0); //临时数组,下面会用
for (int merge_step = 1; merge_step < len; merge_step <<= 1)//当merge_step为k,表示merge两个长度k的有序序列成一个长度2k的序列
{
for (int begin = 0; begin < len - merge_step; begin += (merge_step << 1))
{
int le = begin, ri = begin + merge_step; //左右区间起点
int le_end = ri, ri_end = min(ri + merge_step, len); //左右区间终点(半闭半开区间)
int i = 0;
while (le < le_end and ri < ri_end)
{
if (nums[le] < nums[ri])
{
temp[i] = nums[le];
++le;
}
else
{
temp[i] = nums[ri];
++ri;
}
++i;
}
while (le < le_end)
{
temp[i] = nums[le];
++i;
++le;
}
while (ri < ri_end)
{
temp[i] = nums[ri];
++i;
++ri;
}
for (int j = 0; j < i; ++j) //写回原数组
{
nums[begin + j] = temp[j];
}
}
}
} void InitiateRandomVector(vector<int>& nums)
{
srand(0);
for (auto& num : nums)
{
num = rand();
}
}
int partition(vector<int>&nums,int le,int ri) //划分区间函数
{
srand(0);
int rand_num=le+rand()%(ri-le); //随机生成一个索引
swap(nums[ri],nums[rand_num]); //换到结尾
int stable=nums[ri];
int i=le-1,j=le;
while(j<ri)
{
if(nums[j]<stable)
{
int temp=nums[j];
nums[j]=nums[++i];
nums[i]=temp; //i存的都是小于基准数的值
}
++j;
}
swap(nums[i+1],nums[ri]);
return i+1; //返回基准数的索引
}
void quick_sort(vector<int>& nums,int le,int ri) //[le,ri]闭区间
{
if(le>=ri)
{
return;
}
int mi=partition(nums,le,ri);
quick_sort(nums,le,mi-1);
quick_sort(nums,mi+1,ri);
}
void QuickSort_Recursion(vector<int>& nums) //递归版
{
quick_sort(nums,0,nums.size()-1);
} void QuickSort_Iteration(vector<int>&nums) //迭代版
{
if(nums.empty())
{
return;
}
stack<int> sta;
sta.push(0);
sta.push(nums.size()-1);
int le,ri,mi;
while(!sta.empty())
{
ri=sta.top(); //后push的右边界故先pop
sta.pop();
le=sta.top();
sta.pop();
mi=partition(nums,le,ri);
if(mi-1>le)
{
sta.push(le);
sta.push(mi-1);
}
if(mi+1<ri)
{
sta.push(mi+1);
sta.push(ri);
}
}
}
int main(int argc, char** argv)
{
cout<<"Input data size:";
int siz;
cin>>siz;
vector<int>nums(siz);
cout<<"Data size:"<<siz<<endl;
InitiateRandomVector(nums);
int t1=time(0);
MergeSort(nums);
cout<<"My merge sort time:"<<time(0)-t1<<"s"<<endl;
InitiateRandomVector(nums);
t1=time(0);
QuickSort_Recursion(nums);
cout<<"My quick sort(recursion) time:"<<time(0)-t1<<"s"<<endl;
InitiateRandomVector(nums);
t1=time(0);
sort(nums.begin(),nums.end());
cout<<"STL sort time:"<<time(0)-t1<<"s"<<endl;
InitiateRandomVector(nums);
t1=time(0);
QuickSort_Iteration(nums);
cout<<"My quick sort(iteration) time:"<<time(0)-t1<<"s"<<endl;
getchar();
return 0;
}

归并非递归、快排递归及非递归的C++实现及时间效率对比。。的更多相关文章

  1. 快排(golang实现) 递归方法

    递归方法,逻辑简洁清晰.这个算法还是很重要的,需要重点记忆理解,面试经常考手写.据说是与傅里叶变换等并称“20世纪十大算法”.https://blog.csdn.net/v_JULY_v/articl ...

  2. 先贴上代码:Random快排,快排的非递归实现

    设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为主元,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序.值得注意的是, ...

  3. C语言 | 栈的应用 | 非递归栈实现快排

    /* 非递归栈实现快排 */ #include <stdio.h> #include <math.h>> #include <malloc.h> #inclu ...

  4. java面试-公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解

    一.公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解 公平锁:多个线程按照申请的顺序来获取锁. 非公平锁:多个线程获取锁的先后顺序与申请锁的顺序无关.[ReentrantLock 默认非公平.s ...

  5. 数据结构(3) 第三天 栈的应用:就近匹配/中缀表达式转后缀表达式 、树/二叉树的概念、二叉树的递归与非递归遍历(DLR LDR LRD)、递归求叶子节点数目/二叉树高度/二叉树拷贝和释放

    01 上节课回顾 受限的线性表 栈和队列的链式存储其实就是链表 但是不能任意操作 所以叫受限的线性表 02 栈的应用_就近匹配 案例1就近匹配: #include <stdio.h> in ...

  6. 排序 之 快排、归并、插入 - <时间复杂度>----掌握思想和过程

    俗话说:天下武功无坚不破,唯快不破.对于算法当然也是要使用时间最短.占用空间最小的算法来实现了. 注意:我代码里面打的备注仅供参考,建议不要背模板(因为没有固定的模板),可以写一个数列按着代码跑两圈或 ...

  7. Java 排序(快排,归并)

    Java 排序有Java.util.Arrays的sort方法,具体查看JDK API(一般都是用快排实现的,有的是用归并) package yxy; import java.util.Arrays; ...

  8. java——快排、冒泡、希尔、归并

    直接贴代码 快排: public class Test { private static void sort(int[] nums){ if(nums == null || nums.length = ...

  9. Java常见的几种排序算法-插入、选择、冒泡、快排、堆排等

    本文就是介绍一些常见的排序算法.排序是一个非常常见的应用场景,很多时候,我们需要根据自己需要排序的数据类型,来自定义排序算法,但是,在这里,我们只介绍这些基础排序算法,包括:插入排序.选择排序.冒泡排 ...

随机推荐

  1. LINUX使用SSH远程终端时,如何将运行时间长的程序在后台挂起,下次SSH登陆时继续使用同一个SHELL?

    我在某个平台上购买了一个云服务器,LINUX操作系统无图形化界面,硬盘空间较小.虽然在平台上可以通过其自带网页版VNC界面登陆SHELL进而操控云主机,但是每次需要操控都得打开网页登陆进平台,然后再进 ...

  2. vue 中的路由为什么 采用 hash 路由模式,而不是href超链接模式(Hypertext,Reference)?

    1. vue中路由模式的种类有两种 1. 一种是 hash 模式. 2. 一种是 h5 的 history 模式. 2. hash 和 history 都是来自 bom 对象 bom 来自 windo ...

  3. css 单位之px , em , rem

    px : Pixel像素单位.像素是相对显示器分辨率而言.em : 相对长度单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px).rem : 相对单 ...

  4. C++-POJ3274-Gold Balanced Lineup[hash]

    不是很懂? 胡乱hash #include <set> #include <map> #include <cmath> #include <queue> ...

  5. SQL注入 盲注

    来源:http://www.cnblogs.com/cheatlove/articles/384233.html SQL注入攻击: (1) 脚本注入式的攻击(2) 恶意用户输入用来影响被执行的SQL脚 ...

  6. java i++与++i的区别

    i++是先赋值,然后再自+1:++i是先自+1,后赋值. 用代码表示就是: 若 a = i++; 则等价于 a=i;i=i+1; 而 a = ++i; 则等价于 i=i+1;a=i; 例子: int ...

  7. DOJ1187 : 重建家园 (分数规划 && 二分 && kruskal)

    最优答案一定是一颗树 那么二分比值,不断kruskal找到最大可以满足的解就可以了 代码如下 #include <cstdio> #include <algorithm> us ...

  8. BZOJ1015[JSOI2008]星球大战starwar题解报告

    题目链接 考虑正序去除点去掉其所有连边十分复杂,可以倒序离线处理,每次新建一个点,连接其连边,用并查集统计联通块的个数. 附代码 #include<iostream> #include&l ...

  9. vue项目接入百度地图

    方法一 :使用第三方工具 vue-baidu-map 安装命令: yarn add vue-baidu-map --save 文档地址:https://dafrok.github.io/vue-bai ...

  10. MongoDB 在Windows环境的下载、安装、配置

    MongoDB4.0在Windows环境的下载.安装.配置 今天本想玩玩MongoDB,可因工作机上未下载Linux虚拟机,下载多耗时.无奈只能先下载Windows版本耍耍.不料,Windows在安装 ...