-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from julycoding/master
merge master to my own repo
- Loading branch information
Showing
31 changed files
with
2,633 additions
and
733 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
第三章:寻找最小的 k 个数 | ||
=============================================================== | ||
|
||
## 第一节、寻找最小的k个数 | ||
|
||
### 1.1题目描述: | ||
|
||
输入一个数组和整数k,从中找到最小的k个数,例如输入数组为A = {1,9,2,4,7,6,3},整数k为3,则输出最小的3个数分别为{1,2,3}。 | ||
|
||
分析:学习和掌握了基本排序算法都知道,此问题可以通过排序来解决,即对A数组进行排序,然后输出前k个数即可,时间复杂度为O(nlogn);再者考虑到运行效率,对前k个数进行排序并维护一个长度为k的排序数组,然后向此输入中插入剩下的n-k(假设A数组大小为n)个数,这样做在k较小时效果较好,而当k的大小与n相近时,此方法的效果还不如前者。假设插入n-k的元素的过程采用二分搜索,则时间复杂度为O(klogk+(n-k)logk)。 | ||
|
||
而最简便的方法是通过构造堆结构来解决问题,即维护一个大小为k的最大堆的数据结构,然后将剩余的n-k个数依次插入此堆结构中,最后输出此数组即可,由于题目并没有要求要对这最小的k个数排序,故可直接输出。 | ||
|
||
### 1.2算法实现: | ||
|
||
```c | ||
//获取父节点指针 | ||
int GetParent(int* pArray,int* pLast) | ||
{ | ||
if(pLast >= pArray) | ||
return (pLast - pArray + 1)/2 - 1; | ||
else | ||
return -1; | ||
} | ||
|
||
//获取左孩子节点指针 | ||
int GetLeft(int* pArray,int* pLast) | ||
{ | ||
if(pLast >= pArray) | ||
return (pLast - pArray + 1)*2 - 1; | ||
else | ||
return -1; | ||
} | ||
|
||
//获取右孩子节点指针 | ||
int GetRight(int* pArray,int* pLast) | ||
{ | ||
if(pLast >= pArray) | ||
return (pLast - pArray + 1)*2; | ||
else | ||
return -1; | ||
} | ||
|
||
//交换两个元素的值 | ||
void Swap(int* pa,int* pb) | ||
{ | ||
int temp = *pa; | ||
*pa = *pb; | ||
*pb = temp; | ||
} | ||
|
||
//最大化堆过程,保持最大堆性质,即父节点元素值大于等于其子孙节点元素 | ||
void MaxHeapify(int* pArray, const int nLength, const int nI) | ||
{ | ||
if((nI < 0) || (pArray == NULL) || (nI > nLength)) | ||
{ | ||
return; | ||
} | ||
int nLeft = GetLeft(pArray,pArray+nI); //获取当前节点的左儿子索引 | ||
int nRight = GetRight(pArray,pArray+nI); //获取当前节点的右儿子索引 | ||
int* pLargest = NULL; //初始化记录最大值的指针 | ||
//若当前元素小于左儿子,则对最大值指针赋值为左儿子指针 | ||
if((nLeft < nLength) && (*(pArray + nI) < *(pArray + nLeft))) | ||
{ | ||
pLargest = pArray + nLeft; | ||
} | ||
else | ||
{ | ||
pLargest = pArray + nI; | ||
} | ||
//若右儿子元素大于最大值元素,则对最大值指针赋值 | ||
if((nRight < nLength) && (*(pLargest) < *(pArray + nRight))) | ||
{ | ||
pLargest = pArray + nRight; | ||
} | ||
//当前元素指针不为最大值,则交换最大值与当前元素值 | ||
if(pLargest != (pArray + nI)) | ||
{ | ||
Swap(pLargest,(pArray + nI)); | ||
{ | ||
//对交换后后的子堆递归进行堆的最大化过程 | ||
MaxHeapify(pArray, nLength, pLargest - pArray); | ||
} | ||
} | ||
} | ||
|
||
//建立最大堆函数 | ||
int BuildMaxHeap(int* pArray,int* pLast) | ||
{ | ||
if((pArray == NULL) || (pLast == NULL)) | ||
{ | ||
return -1; | ||
} | ||
int nLength = pLast - pArray + 1; //获取当前堆数组长度 | ||
int nMid = nLength / 2; | ||
//对数组的前半数据进行堆最大化过程,因为后半部分数据为叶子节点数据,已经保持了最大堆性质 | ||
for(int i=nMid;i>=0;i--) | ||
{ | ||
MaxHeapify(pArray,nLength,i); | ||
} | ||
return 0; | ||
} | ||
|
||
//寻找数组中最小的k个数,考虑到对空间的有效利用,这里数组pArray的前k项即为最小的k个数,函数正确返回0,错误返回-1 | ||
int FindMinimumK(int* pArray,int nLength,int k) | ||
{ | ||
int nIndex = 0; | ||
|
||
if((pArray == NULL) || (nLength <= 0) || (k <= 0)) | ||
return -1; | ||
|
||
BuildMaxHeap(pArray, pArray + k - 1); | ||
|
||
for(nIndex = k; nIndex < nLength; nIndex++) | ||
{ | ||
if(pArray[0] > pArray[nIndex]) | ||
{ | ||
Swap(&pArray[0],&pArray[nIndex]); | ||
MaxHeapify(pArray, k, 0); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int Array[] = {9,8,6,4,1,2,3}; | ||
int k = 3; | ||
int i = 0; | ||
printf("The %d minimum number in Array are:\n",k); | ||
FindMinimumK(Array,sizeof(Array)/sizeof(int),k); | ||
for(i = 0;i < k; i++) | ||
{ | ||
printf("%d ",Array[i]); | ||
} | ||
printf("\n"); | ||
return 0; | ||
} | ||
|
||
``` | ||
同样,若想寻找最大的k个数,则可通过构造大小为k的最小堆来实现以上操作,读者可考虑如何通过修改以上代码完成。 |
Oops, something went wrong.