【编程练习】空间复杂度为O(1)的线性排序原理及编程(GNU C实现)
2014-04-07 10:08
435 查看
题目:(腾讯面试题)
一个大小为N的数组,里面是N个整数,假设都为正数,怎样去除重复的整数,使其值为0。
其他类型题目:
一个数组。里面的数据两两相同,只有两个数据不同,要求找出这两个数据。要求时间复杂度0(N)空间复杂度O(1)。
编程要点:
切记数组的传参数为指针,函数体内只能当指针使用,sizeof(A)为4;
思想:
首先,去重,我们先排序这些数,若涉及到比较排序,考虑到所有的情况,则时间复杂度至少是O(nlgn),因此,只能考虑到线性排序,但需要空间复杂度为O(1),则线性排序淘汰,考虑基数排序,基数排序采用位排序,若采用十进制位排序,则对位本身排序需要线性,空间复杂度不为O(1),采用二进制位排序,使用快排划分,保证对位排序的稳定,则可稳定,但是由于对低位排序时,快排无法保持稳定。采用高位排序时,采用分组快排,即如前K位已排序成功,则对第K+1位进行快排排序时,只针对前K位相同的情况,不相同的情况跳过,进行下此次快排。
本程序在高位分组快排时,采用三个指向索引,分别指向0的末位,指向1的起始位,指向1的末位,然后每一次的排序,则针对这三个索引进行更新,和值交换。
然后,排序好的数组,只需遍历一遍,即可去掉重数。
程序实现:
一个大小为N的数组,里面是N个整数,假设都为正数,怎样去除重复的整数,使其值为0。
其他类型题目:
一个数组。里面的数据两两相同,只有两个数据不同,要求找出这两个数据。要求时间复杂度0(N)空间复杂度O(1)。
编程要点:
切记数组的传参数为指针,函数体内只能当指针使用,sizeof(A)为4;
思想:
首先,去重,我们先排序这些数,若涉及到比较排序,考虑到所有的情况,则时间复杂度至少是O(nlgn),因此,只能考虑到线性排序,但需要空间复杂度为O(1),则线性排序淘汰,考虑基数排序,基数排序采用位排序,若采用十进制位排序,则对位本身排序需要线性,空间复杂度不为O(1),采用二进制位排序,使用快排划分,保证对位排序的稳定,则可稳定,但是由于对低位排序时,快排无法保持稳定。采用高位排序时,采用分组快排,即如前K位已排序成功,则对第K+1位进行快排排序时,只针对前K位相同的情况,不相同的情况跳过,进行下此次快排。
本程序在高位分组快排时,采用三个指向索引,分别指向0的末位,指向1的起始位,指向1的末位,然后每一次的排序,则针对这三个索引进行更新,和值交换。
然后,排序好的数组,只需遍历一遍,即可去掉重数。
程序实现:
#include<stdio.h> #include<stdlib.h> void serial_sort(unsigned int A[], int length) { unsigned int bit, i, current_high_bits, pre_high_bits; unsigned int first_index_1, last_index_1, last_index_0; for(bit = 32; bit >=1; bit--){ pre_high_bits = -1; for(i = 0; i < length; i++){ unsigned char x = (A[i] >> (bit - 1)) & 0x01; //obtain sort bit current_high_bits = A[i] >> bit; //obtain high bits if(i == 0 || current_high_bits != pre_high_bits){ pre_high_bits = current_high_bits; first_index_1 = -1; last_index_1 = -1; last_index_0 = -1; if(x == 1){ first_index_1 = i; last_index_1 = i; } else { last_index_0 = i; } continue; } if(current_high_bits == pre_high_bits){ //same, we should sort if(x == 0){ if(first_index_1 == -1){ last_index_0++; }else{ unsigned int m = A[first_index_1]; A[first_index_1] = A[i]; A[i] = m; last_index_0 = first_index_1; first_index_1++; last_index_1++; } }else{ if(first_index_1 == -1){ first_index_1 = i; last_index_1 = i; }else{ last_index_1++; } } } } } } void delete_dup(unsigned int A[], int length) { int i; int pre; for(i = 0; i < length; i++){ if(i == 0){ pre =A[i]; continue; } if(A[i] == pre){ A[i] = 0; }else{ pre = A[i]; } } } int main(void) { unsigned int A[] = {1,3,2,1,5,99,81,4,6,9,5,6,2,55,4,100,12,24,6,75,23,99,89,1080,45,60,81,10000,2}; int i; printf("prev A[]:"); for(i = 0; i < sizeof(A) /sizeof(A[0]) ; i++){ printf("%d ", A[i]); } printf("\n"); serial_sort(A, sizeof(A) /sizeof(A[0])); printf("sort A[]:"); for(i = 0; i < sizeof(A) /sizeof(A[0]) ; i++){ printf("%d ", A[i]); } printf("\n"); delete_dup(A, sizeof(A) /sizeof(A[0])); printf("final A[]:"); for(i = 0; i < sizeof(A) /sizeof(A[0]) ; i++){ printf("%d ", A[i]); } printf("\n"); return 0; }
相关文章推荐
- 独创的PHP模板类
- java导出excel
- 安装MATLAB_R2013b_X64_x32激活及破解方法
- 长浮点数的加法
- C++ 智能指针详解
- C++ 智能指针Auto_PTR 分析
- GoldenGate学习之旅-4(添加表级别的补充日志)
- Google的十个核心技术
- 在Ubuntu中安装Python命令
- 《Java Concurrency in Practice》之发布(Publication)和逸出(escape)
- 【走进Lua的世界之三】lua的堆栈到底为何物?
- C++个人学习笔记02
- C++ 关键字 explicit, export, mutable
- java操作Excel示例
- 图文例解C++类的多重继承与虚拟继承
- C++ static、const和static const 以及它们的初始化
- C++ 箭头-> 双冒号:: 点号.操作符区别
- 关于编程 现在那种语言比较热门 容易上手
- 仅通过崩溃地址找出源代码的出错行
- php使用json_encode对变量json编码