查找最小的k个元素

给定一个数组和一个k,输出最小的k个数字。

这个问题有多重解法,譬如:
1、sort, top K,时间复杂度O(nlogn)
2、小顶堆排序,pop+调整k次,时间复杂度O(n+klogn)。
3、选择排序,每次选min,swap到头部时间复杂度O(nk)。

这里写下选择排序这个。
#include <stdio.h>

void select_min(int* arr, int n, int k)
{
int i, j, tmp;
int min[......]

继续阅读

在二叉树中找出和为某一值的所有路径

题目:输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所经过的所有结点形成一条路径。
打印出和与输入整数相等的所有路径。

例如:

10
/     \
5       12
/ \
4   7

输入整数22,输出如下路径:

10  12
10  5  7

解:就是最简单的先序遍历,只不过要记录路径,可以使用数组,我这里用的stl::vector。

注意left和right遍历后,要回退当前结点在path中状态。

算法:
v[......]

继续阅读

数据结构重读 – 赫夫曼树(最优二叉树)

路径长度:从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称作路径长度。

树的路径长度:从树根到每一个结点的路径长度之和。

结点的带全路径长度:从该结点到树根之间的路径长度与结点上权的乘积。

树的带全路径长度:树中所有叶子结点的带全路径长度之和,WPL = Σ (wi x li),其中wi是叶子结点的权重,li是从根到该叶子结点的路径长度,注意,带全路径长度只有叶子结点有权重!其他结点只计算长度无权重!

来看书上三个树的WPL:

[......]

继续阅读

数据结构重读 – 树和等价问题(并查集)

数据结构这书感觉和之前没读过一样……以前从来没发现树这章还讲了并查集……

若R是集合S上的一个等价关系,则由这个等价关系可以产生这个集合的唯一划分。

如何划分等价类

假设集合S有n个元素,m个形如(x, y),的等价偶对(x, y都是集合S中的元素)。

(1)令S中每个元素各自形成一个只含单个成员的子集,记作S1, S2, ..., Sn。
(2)依次读入m个偶对,对每个读入的偶对(x, y),判定x和y所属的集合,若他们还不属于同一集合,设x属于Si,y属于Sj,则合[......]

继续阅读

数据结构重读 - 树和森林

树的存储,不再限于二叉树了。

1、双亲标示法
虽然每个结点可能有多个孩子,但是每个孩子只可能有一个双亲,这是固定的。
于是有了双亲标示法。
每个孩子存在数组中,孩子记录其双亲的位置。
如果根据某个孩子找双亲,可以几乎在常数时间搞定(反复调用PARENT(T, X),直到X为根为止)。
但是如果要从树根往下遍历求孩子结点,则需要遍历整个数组,会很慢。

typedef struct PTNode
{
int data;
int parent;
};

typdef[......]

继续阅读