熱點問題演算法思考(一)
阿新 • • 發佈:2019-02-09
最近看了一些技術書籍,覺得大資料分析/儲存以及雲平臺必然會成為未來網際網路發展的方向。
對於大資料思考如下問題:
快取中快取了一天的搜尋詞條,假設詞條大小為1~255位元組不等,那麼如果最快找出其中最熱門的N個搜尋詞條;
這應該是搜尋公司每天都要做的事情,而且資料量也一定非常巨大。
那麼怎麼以最節省的方式來統計便是一個可以思考的東西了。
先假設一個簡化的模型:
假如我有一個超級大的陣列,那麼我要取出其中最小的k個數,該怎麼做到?
我的實現思路就是先建立一個大小為K的樹,然後一個一個輸入陣列中的數,用一個函式來維護樹。這樣樹中就記錄著大陣列中最小的k個數。
假設大陣列總長度為N,這樣整個計算的複雜度就是n+n*k;複雜度與想象中的有點差別。對於演算法與資料結構,接下來再更新。
我目前的實現程式碼如下:
#include <iostream> #include <string> #define MAX 9999 //單個樹節點的定義 typedef struct S_NODE { int value; S_NODE *m_leftNode; S_NODE *m_rightNode; } *PNODE; //建立一個大小為k的二叉樹 S_NODE* create(int start, int k) { if (k==0) { return NULL; } S_NODE *node = new S_NODE; node->value = start; k--; int i=k/2; node->m_leftNode = create(start-i, k-i); node->m_rightNode = create(start+i, i); return node; } //列印樹的資訊 void printnode(S_NODE *node) { if (node==NULL) return; if (node->m_leftNode) { printnode(node->m_leftNode); } std::cout<<node->value<<" "; if (node->m_rightNode) { printnode(node->m_rightNode); } } //不停得讀取新的數,吸取小數,扔掉大數 int input(S_NODE *node, int value) { if (node==NULL) { return MAX; } int temp = value; if (value>node->value) { if (node->m_rightNode) return input(node->m_rightNode, value); else return value; } else { if (node->m_leftNode) { temp = input(node->m_leftNode, value); value = node->value; node->value = temp; if (node->m_rightNode) { temp = input(node->m_rightNode, value); value = temp; } } else if(node->m_rightNode) { temp = input(node->m_rightNode, value); } else { temp = node->value; node->value = value; value = temp; } } return temp; } //測試函式 int main(int argc, const char * argv[]) { int temp; S_NODE *root = create(100, 7); while (1) { printnode(root); std::cout<<"\n"; sleep(1); temp = rand()%100; std::cout<<temp<<" -- "; if (temp<0) { break; } input(root, temp); } std::cout << "Hello, World!\n"; return 0; }
執行結果: