首页 > 代码库 > 剑指Offer28 最小的K个数
剑指Offer28 最小的K个数
包含了Partition函数的多种用法
以及大顶堆操作
1 /************************************************************************* 2 > File Name: 28_KLeastNumbers.cpp 3 > Author: Juntaran 4 > Mail: JuntaranMail@gmail.com 5 > Created Time: 2016年08月31日 星期三 19时45分41秒 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <bits/stdc++.h> 10 11 using namespace std; 12 13 14 // 大顶堆求最小K个数 15 typedef multiset<int, greater<int> > intSet; 16 typedef multiset<int, greater<int> >::iterator setIterator; 17 18 void GetKLeastNumbers2(int* data, intSet& leastNumbers, int length, int k) 19 { 20 leastNumbers.clear(); 21 22 if (k<1 || length<k) 23 return; 24 25 for (int i = 0; i < length; ++i) 26 { 27 if (leastNumbers.size() < k) 28 leastNumbers.insert(data[i]); 29 30 else 31 { 32 setIterator Greatest = leastNumbers.begin(); 33 if (data[i] < *(leastNumbers.begin())) 34 { 35 leastNumbers.erase(Greatest); 36 leastNumbers.insert(data[i]); 37 } 38 } 39 } 40 41 for (setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter) 42 { 43 printf("%d ", *iter); 44 } 45 printf("\n"); 46 } 47 48 49 void swap(int* p, int* q) 50 { 51 int temp = *p; 52 *p = *q; 53 *q = temp; 54 } 55 56 // Partition函数应用 57 int Partition(int* data, int length, int start, int end) 58 { 59 if (data=http://www.mamicode.com/=NULL || length<=0 || start<0 || end>=length) 60 return -1; 61 62 // 令数组第一个数字为标杆 63 int index = start; 64 65 // 标杆与数组最后一个元素交换 66 swap(&data[index], &data[end]); 67 68 int small = start - 1; 69 for (index = start; index < end; ++index) 70 { 71 if (data[index] < data[end]) 72 { 73 ++ small; 74 if (small != index) 75 { 76 swap(&data[index], &data[small]); 77 } 78 } 79 } 80 ++ small; 81 swap(&data[small], &data[end]); 82 83 return small; 84 } 85 86 // 利用Partiton实现快排 87 void quickSort(int* data, int length, int start, int end) 88 { 89 if (start==end || data=http://www.mamicode.com/=NULL || length<=0) 90 return; 91 92 int index = Partition(data, length, start, end); 93 // printf("index is %d\n", index); 94 if (index > start) 95 quickSort(data, length, start, index-1); 96 if (index < end) 97 quickSort(data, length, index+1, end); 98 } 99 100 // 利用Partition寻找出现次数超过一半的数 (中位数)101 int GetMoreThanHalf(int* input, int length)102 {103 if (input==NULL || length<=0)104 return -1;105 int start = 0;106 int end = length - 1;107 int index = Partition(input, length, start, end);108 int middle = length >> 1;109 while (index != middle)110 {111 if (index > middle)112 {113 end = index - 1;114 index = Partition(input, length, start, end);115 }116 else117 {118 start = index + 1;119 index = Partition(input, length, start, end);120 }121 }122 int ret = input[middle];123 // 检验是否正确124 int count2 = 0;125 for (int i = 0; i < length; ++i)126 {127 if (input[i] == ret)128 count2 ++;129 }130 if (count2*2 > length)131 {132 printf("middle number is %d\n", input[middle]);133 return ret;134 }135 else136 {137 printf("Not Find\n");138 return -1;139 }140 }141 142 143 // 利用Partition寻找第K小的数144 int GetKthNumber(int* input, int length, int k)145 {146 if (input==NULL || length<=0 || k<=0 || k>length)147 return -1;148 int start = 0;149 int end = length - 1;150 int index = Partition(input, length, start, end);151 while (index != k - 1)152 {153 if (index > k-1)154 {155 end = index-1;156 index = Partition(input, length, start, end);157 }158 else159 {160 start = index + 1;161 index = Partition(input, length, start, end);162 }163 }164 printf("Kth is %d\n", input[index]);165 return input[index];166 }167 168 169 // 利用Partition寻找最小K个数170 void GetKLeastNumbers(int* input, int length, int* output, int k)171 {172 if (input==NULL || output==NULL || length<=0 || k<=0 || k>length)173 {174 return;175 }176 int start = 0;177 int end = length - 1;178 int index = Partition(input, length, start, end);179 while (index != k - 1)180 {181 if (index > k-1)182 {183 end = index - 1;184 index = Partition(input, length, start, end);185 }186 else187 {188 start = index + 1;189 index = Partition(input, length, start, end);190 }191 // printf("index is %d\n", index);192 }193 for (int i = 0; i < k; ++i)194 output[i] = input[i];195 196 for (int i = 0; i < k; ++i)197 printf("%d ", output[i]);198 printf("\n");199 }200 201 // 利用大顶堆寻找最小K个数202 203 204 int main()205 {206 int k = 5;207 int nums[] = {3,5,5,5,6,5,7,1,2,9};208 int length = 10;209 int output[k] = {0};210 211 // 快速排序212 quickSort(nums, length, 0, length-1);213 for (int i = 0; i < length; ++i)214 printf("%d ", nums[i]);215 printf("\n");216 217 // 求最小K个数218 GetKLeastNumbers(nums, length, output, k);219 220 // 求第K大的数221 GetKthNumber(nums, length, k);222 223 // 求数组中超过一半的数(中位数)224 GetMoreThanHalf(nums, length);225 226 // 大顶堆求最小K个数227 intSet leastNumbers;228 GetKLeastNumbers2(nums, leastNumbers, length, k);229 }
剑指Offer28 最小的K个数
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。