70 数组的Kmin算法和二叉搜索树的Kmin算法对比
【本文链接】
http://www.cnblogs.com/hellogiser/p/kmin-of-array-vs-kmin-of-bst.html
【分析】
数组的Kmin算法和二叉搜索树的Kmin算法非常类似,其本质是找序列中的第K大或者第K小的元素,可以借鉴QuickSort的思想加以实现。
【Kmin_of_Array】
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
// 70_Kmin_of_Array_and_BST.cpp : Defines the entry point for the console application.
// /* version: 1.0 author: hellogiser blog: http://www.cnblogs.com/hellogiser date: 2014/9/18 */ #include "stdafx.h" #include "iostream" #include <ctime> #include <algorithm> using namespace std; void print(int *a, int n) { for (int i = 0; i < n; i++) { cout << a[i] << " "; } cout << endl; } int compare_less (const void *a, const void *b) { return ( *(int *)a - * (int *)b ); } //======================================================== // kmin of array //======================================================== void myswap(int &a, int &b) { int t = a; a = b; b = t; } int partition1(int *a, int left, int right) { // a[left,...p-1]<=a[p]<a[p+1,...right] int i = left; int j = right; int key = a[left]; while(i < j) { while(a[i] <= key) i++; while(a[j] > key) j--; if (i < j) { myswap(a[i], a[j]); } } // left---j---i---right myswap(a[left], a[j]); return j; } int kmin(int *a, int left, int right, int k) { if(left < = right) { int p = partition1(a, left, right); int pk = p - left + 1; if (k == pk) { return a[p]; } else if (k < pk) { return kmin(a, left, p - 1, k); } else // k >pk { return kmin(a, p + 1, right, k - pk); } } } int Kmin_of_Array(int *a, int n, int k) { if (a == NULL || n <= 0) return -1; if (k < 1 || k > n) return -1; return kmin(a, 0, n - 1, k); } void test_base(int *a, int n, int k) { print(a, n); qsort(a, n, sizeof(int), compare_less); print(a, n); cout << k << " min of array is: " << Kmin_of_Array(a, n, k) << endl; cout << "==============================\n"; } void test_default() { srand((unsigned int)time(NULL)); const int n = 20; int a[n]; for (int i = 0; i < n; i++) { a[i] = rand() % 100; } test_base(a, n, 3); } void test_main() { test_default(); } int _tmain(int argc, _TCHAR *argv[]) { test_main(); return 0; } /* 37 30 22 10 22 63 6 44 36 41 43 75 54 77 9 99 3 13 28 27 3 6 9 10 13 22 22 27 28 30 36 37 41 43 44 54 63 75 77 99 3 min of array is: 9 ============================== */ |
【Kmin_of_BST】
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
//========================================================
// kmin of bst //======================================================== // binary tree node struct struct BinaryTreeNode { int value; BinaryTreeNode *parent; // for rank of bst BinaryTreeNode *left; BinaryTreeNode *right; int size; // for kmin of bst // x.size = x.left.size + x.right.size +1 }; int node_size(BinaryTreeNode *node) { // get node size of node if (node == NULL) return 0; node->size = node_size(node->left) + node_size(node->right) + 1; return node->size; } int left_size(BinaryTreeNode *node) { // get left size of node in o(1) return node->left != NULL ? node->left->size : 0; } BinaryTreeNode *kmin_bst(BinaryTreeNode *root, int k) { if (root == NULL) return NULL; int pk = left_size(root) + 1; // get node rank first if (k == pk) { return root; } else if (k < pk) { return kmin_bst(root->left, k); } else // k>pk { return kmin_bst(root->right, k - pk); } } BinaryTreeNode *Kmin_of_BST(BinaryTreeNode *root, int k) { if (root == NULL) return NULL; // get node size of bst first int nodes = node_size(root); if (k < 1 || k > nodes) return NULL; // use node size info to get kmin of bst return kmin_bst(root, k); } |