2.2 C语言_实现数据容器vector(排序功能)
上一节我们说到我们己经实现了一般Vector可以做到的自动扩充,告诉随机存取,那么现在我们需要完成vector的一个排序的功能。
排序算法我们网上一百度哇~~!很常见的就有8大排序算法;
1.选择排序 2.冒泡排序 3.插入排序 4.快速排序
5.归并排序 6.桶排序 7.堆排序 8.希尔排序
具体的思想本猿就不展开讲啦,现在C语言应用的场景大多数在服务器和嵌入式设备,服务器数据量大,嵌入式设备资源有限
两者是对时间复杂度和空间负责度的两个极端。
一开始我想要优化堆排序,使得堆排序的空间复杂度减小;
优化的思想很简单;我们并不申请一个与原数组大小一致的空间,而是申请一个他的映射数组;
当我们堆排序 insert 和 delete 后,映射数组中就存储了有序数据的信息;
例如:映射数组mapTab[0] = 20; //也就意味着真正有序数组的第0位是现在数组的第20位;将第20位移动至第0位;在有序数组的第20位
现在在哪一个位置;依次跳转映射,将整个映射表遍历后,数组就变成有序的啦;
以下是实现代码:
/*
*
* 此函数为堆排序的改进版本,使用了一个数组作为数据的映射,使用此数组记住当前位置正确的数据下标是多少;
* 例如 数组a[0] = 12;即表示 在真正有序的数据中第 [0] 位应该是现在的第12位数据;但是在这里为了节约空间,
* 将数据的顺序颠倒;也就是说 a[maxsize] 中存放的数字下标就是有序数据的第[0]位;
*
* insert delete后,生成的数组就是我们的映射表,这个是依照迭代的思想,从第0位开始,找出第0位应该存放的数据是第n位,
* 迭代,需要应该在第n位的数据现在在第y位。依次寻找迭代;
* 由此一定会迭代出一个循环,此时将之前缓存起来的第0位数据放入它应该去的位置,同时,自增,查看第1位,如果第1位已经就绪则继续自增
* 性能分析;
* 此方法相对于堆排序,将空间缩减为每个元素只占用5个字节,如果元素类型大小小于5,则使用此方法将浪费空间和时间,
*/
void heapSortInt(VCT_DOU_t *v)
{
u32 *mapTab = (u32 *)malloc(sizeof(u32) * (v->size + ));
// u32 temp[50] = {0};
u32 index = ;
// insert min
for (u32 i = ; i <= v->size; i++)
{
index = i;
for (; index > && v->compare(&v->data[i - ], &v->data[mapTab[(index >> )]]); index >>= )
mapTab[index] = mapTab[index >> ];
mapTab[index] = i - ;
}
// delete min
u32 child = ;
u32 minindex;
for (u32 i = ; i < v->size; i++)
{
minindex = mapTab[];
mapTab[] = mapTab[v->size - i];
index = ;
for (; (index << ) <= (v->size - i - ); index = child)
{
child = (index << );
if (child != (v->size - i - ) && compare(&v->data[mapTab[child + ]], &v->data[mapTab[child]]))
{
child++;
}
if (compare(&v->data[mapTab[child]], &v->data[mapTab[v->size - i]]))
mapTab[index] = mapTab[child];
else
break;
}
mapTab[index] = mapTab[v->size - i];
mapTab[v->size - i] = minindex;
} // double t;
u8 *sta = (u8 *)malloc(sizeof(u8) * v->size);
// u8 sta[50] = {0};
template_t t = {};
memset(sta, , sizeof(u8) * v->size);
for (u32 i = v->size; i > ; i--)
{
printf("\n[%d] %d", i, mapTab[i]);
if (sta[v->size - i] == )
continue;
t = v->data[v->size - i];
u32 start = v->size - i;
u32 next = mapTab[i];
while (next != (v->size - i))
{
v->data[start] = v->data[next];
sta[start] = ;
start = next;
next = mapTab[v->size - next];
}
v->data[start] = t;
sta[start] = ;
}
v->show(v);
}
经过本猿的测试发现,时间消耗是普通堆排序的5倍时间(数组大小10000000);虽然时间复杂度依旧是nlogn,但是我还是不能接受,奈何自己实在没有想到更好的优化方法;
不得已,只能转变策略;
我个人而言对快读排序不太放心,虽然它被广泛使用,但是其性能是不稳定的,而堆排序就很稳定,因此我在头文件中定义了一个宏。如果这个宏有配置使用快排或者堆排序,那么
就使用快排或者堆排序,否则就使用冒泡排序;
现已将代码上传至github:https://github.com/KimAlittleStar/cstd
目录
1.引言
3.2 C语言_实现数据容器set(基础版)
4 C语言_实现简单基础的map
2.2 C语言_实现数据容器vector(排序功能)的更多相关文章
- JavaScript 字符串与数组互转,并保持数据去重、排序功能
var valueArr = new Array(); if( $("input[name='type']").val() != ""){ valueArr = ...
- 3.1 C语言_实现AVL平衡二叉树
[序] 上节我们实现了数据结构中最简单的Vector,那么来到第三章,我们需要实现一个Set set的特点是 内部有序且有唯一元素值:同时各种操作的期望操作时间复杂度在O(n·logn): 那么标准的 ...
- C++关联式容器的排序准则
stl中set和map为关联式容器,会根据排序准将元素自动排序.原型如下: template<class _Kty, class _Pr = less<_Kty>, class _A ...
- R语言 我要如何开始R语言_数据分析师
R语言 我要如何开始R语言_数据分析师 我要如何开始R语言? 很多时候,我们的老板跟我们说,这个东西你用R语言去算吧,Oh,My god!什么是R语言?我要怎么开始呢? 其实回答这个问题很简单,首先, ...
- DataSet的灵活,实体类的方便,DTO的效率:SOD框架的数据容器,打造最适合DDD的ORM框架
引言:DDD的困惑 最近,我看到园子里面有位朋友的一篇博客 <领域驱动设计系列(一):为何要领域驱动设计? >文章中有下面一段话,对DDD使用产生的疑问: •没有正确的使用ORM, 导致数 ...
- SOD框架的数据容器,打造最适合DDD的ORM框架
SOD框架的数据容器,打造最适合DDD的ORM框架 引言:DDD的困惑 最近,我看到园子里面有位朋友的一篇博客 <领域驱动设计系列(一):为何要领域驱动设计? >文章中有下面一段话,对DD ...
- sql 两大类 DDL数据定义语言 和DCL数据控制语言
SQL分为五大类: DDL:数据定义语言 DCL:数据控制语言 DML:数据的操纵语言 DTL:数据事务语言 DQL:数据查询语言. DDL (date definition lang ...
- Netty 中的内存分配浅析-数据容器
本篇接续前一篇继续讲 Netty 中的内存分配.上一篇 先简单做一下回顾: Netty 为了更高效的管理内存,自己实现了一套内存管理的逻辑,借鉴 jemalloc 的思想实现了一套池化内存管理的思路: ...
- 零基础学Python:数据容器
1.常用操作 列表常用操作 在 ipython 中定义一个 列表,例如: l= list() 输入 l. 按下 TAB 键, ipython 会提示 字典 能够使用的函数如下: 可以到官方网址查询使用 ...
随机推荐
- Linux环境下进行分布式压测踩过的坑
背景:公司为了满足大并发的情况,需要测试组配合,就需要分布式压测,这里我把我踩过坑都记录下来: 环境:Linux + jmeter-v.5.1.1;使用3台2核4G的压力机: Q1: Server f ...
- Java位运算符&、|、^、>>、<<、~、>>>
如果要搞懂Java中的位运算符,首先要搞懂二进制的运算,之前一篇有介绍详细请看 二进制运算-十进制与二进制的转换 Java中的位运算符有:&(按位与).|(按位或).^(按位异或).>& ...
- Java设计模式 - 单例模式(创建型模式)
单例模式我在上学期看一些资料时候学习过,没想到这学期的软件体系结构就有设计模式学习,不过看似篇幅不大,介绍得比较简单,在这里我总结下单例模式,一来整理之前的笔记,二来也算是预习复习课程了. 概述 单例 ...
- Qt for Android开发入门
1. Qt for Android环境搭建 1.1 打包需要的工具 1.2 JDK安装 如果之前配置过,就可以跳过这一步. 下载java jdk 64:java jdk 1.8 x64 ...
- .net 和 java 技术对应关系
.net 和 java 技术对应关系 java 生态的优势早已人尽皆知,asp.net core 的生态也呈欣欣向荣之势.作为高级技术从业人,你不应该落下任何一门技术. 如果你正在将你的 java 知 ...
- opencv之霍夫曼变换
霍夫变换不仅可以找出图片中的直线,也可以找出圆,椭圆,三角形等等,只要你能定义出直线方程,圆形的方程等等. 不得不说,现在网上的各种博客质量真的不行,网上一堆文章,乱TM瞎写,误人子弟.本身自己就没有 ...
- SpringBootSecurity学习(11)网页版登录之URL动态权限
动态权限 前面讨论用户登录认证的时候,根据用户名查询用户会将用户拥有的角色一起查询出来,自动实现判断当前登录用户拥有哪些角色.可以说用户与角色之间的动态配置和判断security做的非常不错.不过在配 ...
- 阿里云centos6.9搭建fastDFS文件服务器
准备压缩包: 1.fastdfs-nginx-module_v1.16.tar.gz 2.FastDFS_v5.05.tar.gz 3.libfastcommonV1.0.7.tar.gz 4.ngi ...
- 阿里云服务器CentOS6.9安装JDK
1:首先查看系统有没有自带jdk rpm -qa | grep java 2:将存在的一一卸载 rpm -ev java-1.7.0-openjdk-1.7.0.141-2.6.10.1.el6_9. ...
- mui中判断是点击还是滑动
判断和滑动是两种触发方式 滑动分为四种,上下左右(swipeup,swipedown,swipeleft,swiperight) 点击分为两种,点击和双击,一般用单机(tap) 根据自己不同的需求进行 ...