堆排序的递归和非递归实现(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; }
相关文章推荐
- [LeetCode]Additive Number
- c语言中的一些小知识
- C++中的资源管理(一):构造自己的auto_ptr与shared_ptr智能指针
- c++学习(函数模板, 类模板)<2>
- c语言如何获取时间
- c++数据类型间的转换
- 2034-人见人爱A-B(c++实现)
- C语言学习——终于认清了的for循环
- C语言基础第二篇--基本数据类型
- volatile的用处
- c和c++中的一维数组和二维数组的动态分配内存,以及参数传递
- C语言基础第一篇--Hello world !
- C++中两个类相互包含引用问题
- C语言函数指针
- 判断从出生到18岁生日一共度过了多少天
- C语言中mktime函数功能及用法
- C++内存使用机制基本概念详解
- C++如何在r3静态调用NT函数
- C语言多继承时子类与基类指针关系,union与struct区别,volatile修饰符作用
- C++ enum用法