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

堆排序的递归和非递归实现(C++版)

2015-11-23 14:39 971 查看
由一道算法面试题所引发的思考:
题目:给定一个数组a, 设计算法判断该数组中是否存在重复的元素。
要求:空间复杂度O(1) 时间复杂度尽量低;


这道题的答案是采用非递归的堆排序算法实现。(时间复杂度O(n) 空间复杂度O(1))

注:如果是递归实现的堆排序 空间复杂度为O(logn)

下面直接贴代码。

堆排序递归:

// 交换元素
void swap(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}

// 建立大根堆
void buildHeap(int *A, int n)
{
for(int i = n / 2; i > -1; --i)
{
adjustHeap(A, i, n);
}
}

// 调整堆
void adjustHeap(int *A, int idx, int n)
{
int ldx = 2 * idx + 1;
int rdx = 2 * idx + 2;
int maxdx = idx;

if(idx <= n / 2)
{
if(ldx < n && A[ldx] > A[maxdx])
{
maxdx = ldx;
}

if(rdx < n && A[rdx] > A[maxdx])
{
maxdx = rdx;
}

// 说明要交换
if(maxdx != idx)
{
swap(A + idx, A + maxdx);
adjustHeap(A, maxdx, n);
}
}
}

// 堆排序
int* heapSort(int* A, int n) {
buildHeap(A, n);

for(int i = n - 1;  i > -1; --i)
{
swap(A, A + i);
adjustHeap(A, 0, i);
}

return A;
}


堆排序非递归:

// 交换元素
void swap(int *p1, int *p2)
{
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}

// 堆排序的非递归解法
void heapSort(vector<int> &v, int n)
{
int size = n;

buildMaxHeap(v, n);

for (int i = n - 1; i >= 1; --i)
{
swap(&v[0], &v[i]);
n--;
adjustHeap(v, 0, n);
}
}

// v    为数组
// idx  为某个堆元素序号
// size 为堆的大小
void adjustHeap(vector<int> &v, int idx, int size)
{
int maxdx, temp;
for(temp = v[idx]; idx * 2 < size; idx = maxdx)
{
maxdx = idx * 2;
if (maxdx + 1 < size && v[maxdx + 1] > v[maxdx])
{
maxdx++;
}
if (v[idx] < v[maxdx])
{
swap(&v[maxdx], &v[idx]);
}
else
{
break;
}
}
}

void buildMaxHeap(vector<int> &v, int n)
{
for (int i = n / 2; i > 0; --i)
{
adjustHeap(v, i, n);
}
}

// 面试题
bool checkDuplicate(vector<int> a, int n) {
// 第二种解法 堆排序(非递归实现)

heapSort(a, n);

bool elemDuplicate = false;
for(int i = 1; i < n; ++i)
{
if(a[i] == a[i - 1])
{
return true;
}
}

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