您的位置:首页 > 编程语言

【编程练习】空间复杂度为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的末位,然后每一次的排序,则针对这三个索引进行更新,和值交换。

然后,排序好的数组,只需遍历一遍,即可去掉重数。



程序实现:

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: