【问题】
对一百万个不相同的数字进行排序,要求时间复杂度O(1),空间复杂度尽可能小!
【分析】
大数据的排序问题,首选方法是“归并”,之前我也写过十亿个数的归并排序算法,且在此基础上的优化方案——大范围内归并小范围内插入排序等等,但本文有一个时间复杂度的要求,归并排序的时间复杂度是O(nlgn),因此我们尝试一种新闻排序算法——“bit排序法”。
“bit排序法”——待排序的数作为bit位的下标,当前位置的bit置为1,一轮遍历待排序数之后,打印出所有当前数值为1的数字下标。
最小的数据结构单位是byte,因此处理起来稍微麻烦了一点
【代码】
package com.hhf; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; /** * bit排序法 * @author HHF * 2015年11月17日17:12:37 * @version 1.0 只支持不同数据的排序 */ public class PhoneNumSort { private static String path = "E:/phoneNum.txt"; private static String resultPath = "E:/phoneNumResult.txt"; private int size = 1000000; public static void main(String[] args) { PhoneNumSort phoneNumSort = new PhoneNumSort(); //生成不相同的一百万个数 phoneNumSort.createNumber(phoneNumSort.size); //统计排序数大小 int bitSize = phoneNumSort.countLineSize(path); //用来保存数据--数组的下标为n,表示数据为8*(n-1)+k byte[] byteData = new byte[bitSize/8 + 1]; phoneNumSort.setByteData(byteData); } /** * 读取文件,并将文件中数值对应到byte类型的打他中去 * @param byteData */ private void setByteData(byte[] byteData){ int index = 0; int n = 0;//第几行 int k = 0;//第几位 try { BufferedReader br = new BufferedReader(new FileReader(path)); String str = br.readLine(); while(str!=null){ index = new Integer(str);//bit中的下标 n = index/8; k = index%8; //设置当前位置的值为1 byteData[n] += getAddNum(k); str = br.readLine(); } br.close(); StringBuffer content = new StringBuffer(); for(int i=byteData.length-1; i>-1; i--){ if(byteData[i]>=128){ byteData[i] -= 128; content.append(8*i + 8).append("\n"); } if(byteData[i]>=64){ byteData[i] -= 64; content.append(8*i + 7).append("\n"); } if(byteData[i]>=32){ byteData[i] -= 32; content.append(8*i + 6).append("\n"); } if(byteData[i]>=16){ byteData[i] -= 16; content.append(8*i + 5).append("\n"); } if(byteData[i]>=8){ byteData[i] -= 8; content.append(8*i + 4).append("\n"); }if(byteData[i]>=4){ byteData[i] -= 4; content.append(8*i + 3).append("\n"); } if(byteData[i]>=2){ byteData[i] -= 2; content.append(8*i + 2).append("\n"); } if(byteData[i]>=1){ content.append(8*i + 1).append("\n"); } } storeDataToFile(resultPath, content.toString().getBytes()); System.out.println(System.currentTimeMillis()+"--排序结果已经写入文件"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 获得每个位置上对应应该要加的数值 * @param pos 位置 * @return 返回该位置对应的数 */ private int getAddNum(int pos){ if(pos>0 && pos<9){ return 1<<(pos-1); }else{ return 0; } } /** * 读取文章的行数 * @param path 文件路径 * @return size 数据量 */ private int countLineSize(String path){ int count = 0; try { BufferedReader br = new BufferedReader(new FileReader(path)); String str = br.readLine(); while(str!=null){ count++; str = br.readLine(); } br.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis()+"--待排序的数据量是"+count); return count; } /** * 生成指定数量的数据 * @param path 文件的路径 * @param size 数据数量 */ private void createNumber(int size){//还是需要先 定义InputStream输入流对象 if(size < 1){ return; } StringBuffer content = new StringBuffer(); for(int i=1; i<=size; i++){ content.append(i).append("\n"); } storeDataToFile(path, content.toString().getBytes()); System.out.println(System.currentTimeMillis()+"--文件创建结束 共生成了数据 "+size+" 条"); } /** * 将数据存储到文件中 * @param path * @param content */ private void storeDataToFile(String path, byte[] content){ File file = new File(path); if(!file.exists()){ try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } try { java.io.OutputStream os = new java.io.FileOutputStream(path); java.io.BufferedOutputStream bos = new java.io.BufferedOutputStream(os); bos.write(content); bos.flush();// 将缓冲区中的内容强制全部写入到文件中(不管是否已经全部写入)有点类似于下面的语句 bos.close(); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
--------相关推荐文章---------
《10亿个字符串的排序问题》http://java--hhf.iteye.com/admin/blogs/2166129
《大范围归并小范围插入排序》http://java--hhf.iteye.com/admin/blogs/2163465
相关推荐
`byte[]`(或称字节数组)是一种用于存储一系列字节的数据类型。在许多应用场景中,`byte[]` 被用来表示图像、音频文件、加密数据或其他任何形式的二进制数据。由于其灵活性,`byte[]` 成为了在应用程序中处理二进制...
### Radix Sort (基数排序) 排序算法详解 ...此外,基数排序不适合小规模数据排序,因为其初始化和管理桶的成本较高。 综上所述,基数排序是一种高效稳定的排序算法,在特定场景下能够提供优秀的性能表现。
其次,排序算法是计算机科学中的重要概念,它用于将一组数据按照特定顺序排列。在易语言中,对字节型数组进行排序,常见的算法有冒泡排序、选择排序、插入排序、快速排序等。每种算法都有其优缺点,适用于不同的场景...
- 适合于小型数组或教学用途,但对于大规模数据排序效率较低。 3. **字符串处理**: - 在MIPS汇编语言中,字符串通常作为ASCII字符数组处理。 - 字符串转换涉及到将ASCII码转换为对应的数值。这通常通过减去数字...
1. 数据定义:在汇编程序中,首先需要定义数据段来存储待排序的人名。这可以通过`DB`(Define Byte)或`DW`(Define Word)伪指令完成,根据人名的长度和字符编码选择合适的方式。 2. 子程序(函数):为了实现排序...
- `endaddr dw`: 结束地址,用于排序过程中的循环条件判断。 - `messg1 db 'Name', '$'`: 提示信息,用于要求用户输入商品名称。 - `messg2 db 'Sort name', 13, 10, '$'`: 排序后的提示信息。 - `namectr db 0`...
近年来,许多专家学者提出了许多高效的排序算法,如SISⅢ、Byte快速排序、基于统计的排序Ⅲ、比特位拆分索引排序算法等。 基于Java按位拆分快速排序算法的基本思想是:首先根据数据中的比特对数据进行划分整理,将...
简单类型包括 byte, char, short, int, long, float, double 等数据类型。这些类型不能放在聚集中,只能使用数组。Java 中的 Arrays 类提供了对这些类型的 sort 方法,可以用来对简单类型的数组进行排序。例如: ``...
1. **数据定义**:首先,汇编源代码会定义一个数组,用于存储待排序的数据。这些数据通常用伪指令(如`DB`,Data Byte)来定义,每一项表示一个字节大小的数值。 2. **变量声明**:可能会定义一些辅助变量,如指示...
3. **换行符定义**:用于在输出排序结果后添加换行符。 ##### 函数定义与调用 ```assembly section.text global _start _start: ; 调用冒泡排序算法 call bubble_sort ; 输出排序后的数组 mov eax, 4 ; sys_...
* 整数类型:byte、short、int、long * 浮点数类型:float、double * 字符类型:char * 布尔类型:boolean * 引用类型:String、Array、Vector Java运算符 Java语言提供了多种运算符,包括: * 算术运算符:+、-...
在Java编程中,对List对象进行排序是一个常见的需求,尤其是在处理数据集合时。Java提供了一个便捷的方法`Collections.sort()`,可以直接对实现了`Comparable`接口的List进行排序。然而,当需要根据对象内部的某个...
在编程领域,排序是至关重要的一个环节,尤其是在处理大量数据时。Go语言,作为一种现代、高效且并发性能优秀的系统级编程语言,提供了多种排序方法。本文将深入探讨Go语言中的排序算法,包括冒泡排序和快速排序,并...
堆排序、快速排序和归并排序是经典的排序算法,它们在大数据处理中用于对数据进行预处理或聚合。堆排序利用堆结构保证在O(n log n)的时间复杂度内完成排序;快速排序则通过分治策略快速划分数据;归并排序则通过合并...
"JavaSE对象数组练习题" 本资源是一个JavaSE练习题,旨在帮助学习者熟悉Java编程语言的基本概念和对象数组的处理。下面是对该练习题的详细...通过完成这个练习题,学习者可以熟悉Java编程语言的基本语法和数据结构。
* 数据存储:Bit 是计算机数据量的最小单位,Byte 是计算机信息技术用于计量存储容量和传输容量的一种计量单位 * 数据类型:了解 Bit 和 Byte 在计算机中的应用 3. 排序算法 知识点: * 数据结构:排序算法的概念...
这个教程可能涵盖了Python的基本语法,变量,数据类型,控制结构,函数,模块等方面。 【描述】"A byte of Python中文版和部分示例" 指出该教程已经翻译为中文,便于中文用户阅读理解。"部分示例"意味着教程中包含...
SQL 用于各种数据库的数据类型 Microsoft Access、MySQL 和 SQL Server 所使用的数据类型和范围。 Microsoft Access 数据类型 数据类型 描述 存储 Text 用于文本或文本与数字的组合。最多 255 个字符。 ...
下面将对 Java 基础编程代码进行详解,包括 main() 函数、输入输出、基本数据类型、数组和基本排序算法等。 main() 函数 在 Java 程序中,main() 函数是程序的入口点,是程序执行的开始。main() 函数的定义格式...