3/3, 20«123»

[转]Python资源

2008-6-18 0:54:13 开发者 抢沙发(0)

Python基本安装:

* http://www.python.org/ 官方标准Python开发包和支持环境,同时也是Python的官方网站;
* http://www.activestate.com/ 集成多个有用插件的强大非官方版本,特别是针对Windows环境有不少改进;

Python文档:

* http://www.python.org/doc/current/lib/lib.html Python库参考手册。
* http://www.byteofpython.info/ 可以代替Tutorial使用,有中文译版的入门书籍。
* http://diveintopython.org/ 一本比较全面易懂的入门书,中文版翻译最近进步为很及时的5.4了。
* http://www.python.org/peps/pep-0008.html 建议采用的Python编码风格。
* http://doc.zoomquiet.org/ 包括Python内容的一个挺全面的文档集。

常用插件:

* http://www.pfdubois.com/numpy/ Python的数学运算库,有时候一些别的库也会调用里面的一些功能,比如数组什么的;
* http://www.pythonware.com/products/pil/ Python下著名的图像处理库Pil;
* http://simpy.sourceforge.net/ 利用Python进行仿真、模拟的解决方案;
* Matplotlib 据说是一个用来绘制二维图形的Python模块,它克隆了许多Matlab中的函数, 用以帮助Python用户轻松获得高质量(达到出版水平)的二维图形;
* http://www.amk.ca/python/code/crypto python的加解密扩展模块;
* http://cjkpython.i18n.org/ 提供与python有关的CJK语言支持功能:转码、显示之类。
* Psyco、Pyrex:两个用于提高Python代码运行效率的解决方案;
* Pyflakes、PyChecker、PyLint:都是用来做Python代码语法检查的工具。
* http://wxpython.sourceforge.net/ 基于wxWindows的易用且强大的图形界面开发包wxPython;
* http://www.pygame.org/ 用Python帮助开发游戏的库,也可以用这个来播放视频或者音频什么的,大概依靠的是SDL;
* http://starship.python.net/crew/theller/py2exe/ win下将Python程序编译为可执行程序的工具,是一个让程序脱离Python运行环境的办法,也可以生成Windows服务或者COM组件。其他能完成Python脚本到可执行文件这个工作的还有Gordon McMillan's Installer、Linux专用的freeze以及py2app、setuptools等。不过此类工具难免与一些模块有一些兼容性的问题,需要现用现测一下。
* 嵌入式数据库:BerkeleyDB的Python版,当然还有其他的好多。
* PEAK提供一些关于超轻量线程框架等基础性重要类库实现。

部分常用工具:

* http://www.scons.org/ Java有Ant这个巨火的构建工具,Python的特性允许我们构建更新类型的构建工具,就是scons了。
* Python Sidebar for Mozilla FireFox的一个插件,提供一个用来查看Python文档、函数库的侧边栏。
* IPython 很好用的Python Shell。wxPython发行版还自带了PyCrust、PyShell、PyAlaCarte和PyAlaMode等几个工具,分别是图形界面Shell和代码编辑器等,分别具有不同特点可以根据自己的需要选用。
* Easy Install 快速安装Python模块的易用性解决方案。

推荐资源:

* Parnassus山的拱顶 巨大的Python代码库,包罗万象。既可以从上面下载代码参考学习,同时也是与Python有关程序的大列表。
* Python号星际旅行船 著名Python社区,代码、文档、高人这里都有。
* faqts.com的Python程序设计知识数据库 Python程序设计知识库,都是与Python有关的程序设计问题及解决方法。
* 啄木鸟 Pythonic 开源社区 著名的(也可以说是最好的)国内Python开源社区。

代码示例:

* http://newedit.tigris.org/technical.htm Limodou的NewEdit编辑器的技术手册,讨论了一些关于插件接口实现、i18实现、wxPython使用有关的问题,值得参考。

其他东西:

* http://www.forum.nokia.com/main/0,,034-821,00.html Nokia居然发布了在Series 60系统上运行Python程序(图形界面用wxPython)的库,还有一个Wiki页是关于这个的:http://www.postneo.com/postwiki/moin.cgi/PythonForSeries60 。Python4Symbian这个页面是记录的我的使用经验。
* pyre:使用Python完成高性能计算需求的包,真的可以做到么?还没研究。
* Parallel Python:纯Python的并行计算解决方案。相关中文参考页面
* Pexpect:用Python作为外壳控制其他命令行程序的工具(比如Linux下标准的ftp、telnet程序什么的),还没有测试可用程度如何。
* pyjamas:Google GWT的Python克隆,还处在早期版本阶段。
* Durus:Python的对象数据库。

有意思的东西:

* Howie:用Python实现的MSN对话机器人。
* Cankiri:用一个Python脚本实现的屏幕录像机。

参考资料

* ZDNET文章:学习Python语言必备的资源
* Pythonic Web 应用平台对比
* 在wxPython下进行图像处理的经验 (其实,仅使用wxPython也可以完成很多比较基础的图像处理工作,具体可以参照《wxPython in Action》一书的第12节)
* 通过win32扩展接口使用Python获得系统进程列表的方法
* 如何获得Python脚本所在的目录位置
* Python的缩进问题
* py2exe使用中遇到的问题
* idle的中文支持问题
* 序列化存储 Python 对象

Python IDE

我的IDE选择经验

* http://www.xored.com Trustudio 一个基于Eclipse的、同时支持Python和PHP的插件,曾经是我最喜欢的Python IDE环境,功能相当全了,不过有些细节不完善以致不大好用。
* http://pydev.sourceforge.net/ 另一个基于Eclipse的,非常棒的Python环境,改进速度非常快,现在是我最喜欢的IDE。
* http://www-900.ibm.com/developerWorks/cn/opensource/os-ecant/index.shtml 用 Eclipse 和 Ant 进行 Python 开发
* http://www.die-offenbachs.de/detlev/eric3.html ERIC3 基于QT实现的不错的PYTHON IDE,支持调试,支持自动补全,甚至也支持重构,曾经在Debian下用它,但图形界面开发主要辅助qt,我倾向wxpython,所以最后还是放弃了这个。
* http://www.scintilla.org/ 同时支持Win和Linux的源代码编辑器,似乎支持Python文件的编辑。
* http://boa-constructor.sourceforge.net/ 著名的基于WxPython的GUI快速生成用的Python IDE,但是开发进度实在太差了……
* http://pype.sourceforge.net/ 成熟的Python代码编辑器,号称功能介于EMACS和IDLE之间的编辑器。
* http://www.stani.be/python/spe SPE:号称是一个Full Featured编辑器,集成WxGlade支持GUI设计。

SQLite B+树实现代码

2008-5-13 2:10:49 开发者 抢沙发(0)

 from: http://www.sqlite.com.cn/MySqlite/6/373.Html

C++代码
  1. /* btrees.h */    
  2. /*   
  3. * 平衡多路树的一种重要方案。   
  4. * 在 1970 年由 R. Bayer 和 E. McCreight 发明。   
  5. */    
  6. #define M 1    
  7. /* B 树的阶,即非根节点中键的最小数目。   
  8. * 有些人把阶定义为非根节点中子树的最大数目。   
  9. */    
  10. typedef int typekey;    
  11. typedef struct btnode { /* B-Tree 节点 */    
  12. int d; /* 节点中键的数目 */    
  13. typekey k[2*M]; /* 键 */    
  14. char *v[2*M]; /* 值 */    
  15. struct btnode *p[2*M+1]; /* 指向子树的指针 */    
  16. } node, *btree;    
  17. /*   
  18. * 每个键的左子树中的所有的键都小于这个键,   
  19. * 每个键的右子树中的所有的键都大于等于这个键。   
  20. * 叶子节点中的每个键都没有子树。   
  21. */    
  22.   
  23. /* 当 M 等于 1 时也称为 2-3 树   
  24. * +----+----+   
  25. * | k0 | k1 |   
  26. * +-+----+----+---   
  27. * | p0 | p1 | p2 |   
  28. * +----+----+----+   
  29. */    
  30. extern int btree_disp; /* 查找时找到的键在节点中的位置 */    
  31. extern char * InsValue; /* 与要插的键相对应的值 */    
  32.   
  33. extern btree search(typekey, btree);    
  34. extern btree insert(typekey,btree);    
  35. extern btree delete(typekey,btree);    
  36. extern int height(btree);    
  37. extern int count(btree);    
  38. extern double payload(btree);    
  39. extern btree deltree(btree);    
  40. /* end of btrees.h */    
  41.   
  42. /*******************************************************/  
C++代码
  1. /*******************************************************/    
  2.   
  3. /* btrees.c */    
  4. #include    
  5. #include    
  6. #include "btrees.h"    
  7.   
  8. btree search(typekey, btree);    
  9. btree insert(typekey,btree);    
  10. btree delete(typekey,btree);    
  11. int height(btree);    
  12. int count(btree);    
  13. double payload(btree);    
  14. btree deltree(btree);    
  15.   
  16. static void InternalInsert(typekey, btree);    
  17. static void InsInNode(btree, int);    
  18. static void SplitNode(btree, int);    
  19. static btree NewRoot(btree);    
  20.   
  21. static void InternalDelete(typekey, btree);    
  22. static void JoinNode(btree, int);    
  23. static void MoveLeftNode(btree t, int);    
  24. static void MoveRightNode(btree t, int);    
  25. static void DelFromNode(btree t, int);    
  26. static btree FreeRoot(btree);    
  27.   
  28. static btree delall(btree);    
  29. static void Error(int,typekey);    
  30.   
  31. int btree_disp; /* 查找时找到的键在节点中的位置 */    
  32. char * InsValue = NULL; /* 与要插的键相对应的值 */    
  33. static int flag; /* 节点增减标志 */    
  34. static int btree_level = 0; /* 多路树的高度 */    
  35. static int btree_count = 0; /* 多路树的键总数 */    
  36. static int node_sum = 0; /* 多路树的节点总数 */    
  37. static int level; /* 当前访问的节点所处的高度 */    
  38. static btree NewTree; /* 在节点分割的时候指向新建的节点 */    
  39. static typekey InsKey; /* 要插入的键 */    
  40.   
  41. btree search(typekey key, btree t)    
  42. {    
  43. int i,j,m;    
  44. level=btree_level-1;    
  45. while (level >= 0){    
  46. for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m));    
  47. if (key == t->k){    
  48. btree_disp = i;    
  49. return t;    
  50. }    
  51. if (key > t->k) /* i == t->d-1 时有可能出现 */    
  52. i++;    
  53. t = t->p;    
  54. level--;    
  55. }    
  56. return NULL;    
  57. }    
  58.   
  59. btree insert(typekey key, btree t)    
  60. {    
  61. level=btree_level;    
  62. InternalInsert(key, t);    
  63. if (flag == 1) /* 根节点满之后,它被分割成两个半满节点 */    
  64. t=NewRoot(t); /* 树的高度增加 */    
  65. return t;    
  66. }    
  67.   
  68. void InternalInsert(typekey key, btree t)    
  69. {    
  70. int i,j,m;    
  71.   
  72. level--;    
  73. if (level < 0){ /* 到达了树的底部: 指出要做的插入 */    
  74. NewTree = NULL; /* 这个键没有对应的子树 */    
  75. InsKey = key; /* 导致底层的叶子节点增加键值+空子树对 */    
  76. btree_count++;    
  77. flag = 1; /* 指示上层节点把返回的键插入其中 */    
  78. return;    
  79. }    
  80. for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m));    
  81. if (key == t->k) {    
  82. Error(1,key); /* 键已经在树中 */    
  83. flag = 0;    
  84. return;    
  85. }    
  86. if (key > t->k) /* i == t->d-1 时有可能出现 */    
  87. i++;    
  88. InternalInsert(key, t->p);    
  89.   
  90. if (flag == 0)    
  91. return;    
  92. /* 有新键要插入到当前节点中 */    
  93. if (t->d < 2*M) {/* 当前节点未满 */    
  94. InsInNode(t, i); /* 把键值+子树对插入当前节点中 */    
  95. flag = 0; /* 指示上层节点没有需要插入的键值+子树,插入过程结束 */    
  96. }    
  97. else /* 当前节点已满,则分割这个页面并把键值+子树对插入当前节点中 */    
  98. SplitNode(t, i); /* 继续指示上层节点把返回的键值+子树插入其中 */    
  99. }    
  100.   
  101. /*   
  102. * 把一个键和对应的右子树插入一个节点中   
  103. */    
  104. void InsInNode(btree t, int d)    
  105. {    
  106. int i;    
  107. /* 把所有大于要插入的键值的键和对应的右子树右移 */    
  108. for(i = t->d; i > d; i--){    
  109. t->k = t->k[i-1];    
  110. t->v = t->v[i-1];    
  111. t->p[i+1] = t->p;    
  112. }    
  113. /* 插入键和右子树 */    
  114. t->k = InsKey;    
  115. t->p[i+1] = NewTree;    
  116. t->v = InsValue;    
  117. t->d++;    
  118. }    
  119. /*   
  120. * 前件是要插入一个键和对应的右子树,并且本节点已经满   
  121. * 导致分割这个节点,插入键和对应的右子树,   
  122. * 并向上层返回一个要插入键和对应的右子树   
  123. */    
  124. void SplitNode(btree t, int d)    
  125. {    
  126. int i,j;    
  127. btree temp;    
  128. typekey temp_k;    
  129. char *temp_v;    
  130. /* 建立新节点 */    
  131. temp = (btree)malloc(sizeof(node));    
  132. /*   
  133. * +---+--------+-----+-----+--------+-----+   
  134. * | 0 | ...... | M | M+1 | ...... |2*M-1|   
  135. * +---+--------+-----+-----+--------+-----+   
  136. * |<- M+1 ->|<- M-1 ->|   
  137. */    
  138. if (d > M) { /* 要插入当前节点的右半部分 */    
  139. /* 把从 2*M-1 到 M+1 的 M-1 个键值+子树对转移到新节点中,   
  140. * 并且为要插入的键值+子树空出位置 */    
  141. for(i=2*M-1,j=M-1; i>=d; i--,j--) {    
  142. temp->k[j] = t->k;    
  143. temp->v[j] = t->v;    
  144. temp->p[j+1] = t->p[i+1];    
  145. }    
  146. for(i=d-1,j=d-M-2; j>=0; i--,j--) {    
  147. temp->k[j] = t->k;    
  148. temp->v[j] = t->v;    
  149. temp->p[j+1] = t->p[i+1];    
  150. }    
  151. /* 把节点的最右子树转移成新节点的最左子树 */    
  152. temp->p[0] = t->p[M+1];    
  153. /* 在新节点中插入键和右子树 */    
  154. temp->k[d-M-1] = InsKey;    
  155. temp->p[d-M] = NewTree;    
  156. temp->v[d-M-1] = InsValue;    
  157. /* 设置要插入上层节点的键和值 */    
  158. InsKey = t->k[M];    
  159. InsValue = t->v[M];    
  160.   
  161. }    
  162. else { /* d <= M */    
  163. /* 把从 2*M-1 到 M 的 M 个键值+子树对转移到新节点中 */    
  164. for(i=2*M-1,j=M-1; j>=0; i--,j--) {    
  165. temp->k[j] = t->k;    
  166. temp->v[j] = t->v;    
  167. temp->p[j+1] = t->p[i+1];    
  168. }    
  169. if (d == M) /* 要插入当前节点的正中间 */    
  170. /* 把要插入的子树作为新节点的最左子树 */    
  171. temp->p[0] = NewTree;    
  172. /* 直接把要插入的键和值返回给上层节点 */    
  173. else { /* (d /* 把节点当前的最右子树转移成新节点的最左子树 */    
  174. temp->p[0] = t->p[M];    
  175. /* 保存要插入上层节点的键和值 */    
  176. temp_k = t->k[M-1];    
  177. temp_v = t->v[M-1];    
  178. /* 把所有大于要插入的键值的键和对应的右子树右移 */    
  179. for(i=M-1; i>d; i--) {    
  180. t->k = t->k[i-1];    
  181. t->v = t->v[i-1];    
  182. t->p[i+1] = t->p;    
  183. }    
  184. /* 在节点中插入键和右子树 */    
  185. t->k[d] = InsKey;    
  186. t->p[d+1] = NewTree;    
  187. t->v[d] = InsValue;    
  188. /* 设置要插入上层节点的键和值 */    
  189. InsKey = temp_k;    
  190. InsValue = temp_v;    
  191. }    
  192. }    
  193. t->d =M;    
  194. temp->d = M;    
  195. NewTree = temp;    
  196. node_sum++;    
  197. }    
  198.   
  199. btree delete(typekey key, btree t)    
  200. {    
  201. level=btree_level;    
  202. InternalDelete(key, t);    
  203. if (t->d == 0)    
  204. /* 根节点的子节点合并导致根节点键的数目随之减少,   
  205. * 当根节点中没有键的时候,只有它的最左子树可能非空 */    
  206. t=FreeRoot(t);    
  207. return t;    
  208. }    
  209.   
  210. void InternalDelete(typekey key, btree t)    
  211. {    
  212. int i,j,m;    
  213. btree l,r;    
  214. int lvl;    
  215.   
  216. level--;    
  217. if (level < 0) {    
  218. Error(0,key); /* 在整个树中未找到要删除的键 */    
  219. flag = 0;    
  220. return;    
  221. }    
  222. for(i=0, j=t->d-1; i t->k[m])?(i=m+1):(j=m));    
  223. if (key == t->k) { /* 找到要删除的键 */    
  224. if (t->v != NULL)    
  225. free(t->v); /* 释放这个节点包含的值 */    
  226. if (level == 0) { /* 有子树为空则这个键位于叶子节点 */    
  227. DelFromNode(t,i);    
  228. btree_count--;    
  229. flag = 1;    
  230. /* 指示上层节点本子树的键数量减少 */    
  231. return;    
  232. else { /* 这个键位于非叶节点 */    
  233. lvl = level-1;    
  234. /* 找到前驱节点 */    
  235. r = t->p;    
  236. while (lvl > 0) {    
  237. r = r->p[r->d];    
  238. lvl--;    
  239. }    
  240. t->k=r->k[r->d-1];    
  241. t->v=r->v[r->d-1];    
  242. r->v[r->d-1]=NULL;    
  243. key = r->k[r->d-1];    
  244. }    
  245. }    
  246. else if (key > t->k) /* i == t->d-1 时有可能出现 */    
  247. i++;    
  248. InternalDelete(key,t->p);    
  249. /* 调整平衡 */    
  250. if (flag == 0)    
  251. return;    
  252. if (t->p->d < M) {    
  253. if (i == t->d) /* 在最右子树中发生了删除 */    
  254. i--; /* 调整最右键的左右子树平衡 */    
  255. l = t->p;    
  256. r = t->p[i+1];    
  257. if (r->d > M)    
  258. MoveLeftNode(t,i);    
  259. else if(l->d > M)    
  260. MoveRightNode(t,i);    
  261. else {    
  262. JoinNode(t,i);    
  263. /* 继续指示上层节点本子树的键数量减少 */    
  264. return;    
  265. }    
  266. flag = 0;    
  267. /* 指示上层节点本子树的键数量没有减少,删除过程结束 */    
  268. }    
  269. }    
  270.   
  271. /*   
  272. * 合并一个节点的某个键对应的两个子树   
  273. */    
  274. void JoinNode(btree t, int d)    
  275. {    
  276. btree l,r;    
  277. int i,j;    
  278. l = t->p[d];    
  279. r = t->p[d+1];    
  280.   
  281. /* 把这个键下移到它的左子树 */    
  282. l->k[l->d] = t->k[d];    
  283. l->v[l->d] = t->v[d];    
  284. /* 把右子树中的所有键值和子树转移到左子树 */    
  285. for (j=r->d-1,i=l->d+r->d; j >= 0 ; j--,i--) {    
  286. l->k = r->k[j];    
  287. l->v = r->v[j];    
  288. l->p = r->p[j];    
  289. }    
  290. l->p[l->d+r->d+1] = r->p[r->d];    
  291. l->d += r->d+1;    
  292. /* 释放右子树的节点 */    
  293. free(r);    
  294. /* 把这个键右边的键和对应的右子树左移 */    
  295. for (i=d; i < t->d-1; i++) {    
  296. t->k = t->k[i+1];    
  297. t->v = t->v[i+1];    
  298. t->p[i+1] = t->p[i+2];    
  299. }    
  300. t->d--;    
  301. node_sum--;    
  302. }    
  303. /*   
  304. * 从一个键的右子树向左子树转移一些键,使两个子树平衡   
  305. */    
  306. void MoveLeftNode(btree t, int d)    
  307. {    
  308. btree l,r;    
  309. int m; /* 应转移的键的数目 */    
  310. int i,j;    
  311. l = t->p[d];    
  312. r = t->p[d+1];    
  313. m = (r->d - l->d)/2;    
  314.   
  315. /* 把这个键下移到它的左子树 */    
  316. l->k[l->d] = t->k[d];    
  317. l->v[l->d] = t->v[d];    
  318. /* 把右子树的最左子树转移成左子树的最右子树   
  319. * 从右子树向左子树移动 m-1 个键+子树对 */    
  320. for (j=m-2,i=l->d+m-1; j >= 0; j--,i--) {    
  321. l->k = r->k[j];    
  322. l->v = r->v[j];    
  323. l->p = r->p[j];    
  324. }    
  325. l->p[l->d+m] = r->p[m-1];    
  326. /* 把右子树的最左键提升到这个键的位置上 */    
  327. t->k[d] = r->k[m-1];    
  328. t->v[d] = r->v[m-1];    
  329. /* 把右子树中的所有键值和子树左移 m 个位置 */    
  330. r->p[0] = r->p[m];    
  331. for (i=0; id-m; i++) {    
  332. r->k = r->k[i+m];    
  333. r->v = r->v[i+m];    
  334. r->p = r->p[i+m];    
  335. }    
  336. r->p[r->d-m] = r->p[r->d];    
  337. l->d+=m;    
  338. r->d-=m;    
  339. }    
  340. /*   
  341. * 从一个键的左子树向右子树转移一些键,使两个子树平衡   
  342. */    
  343. void MoveRightNode(btree t, int d)    
  344. {    
  345. btree l,r;    
  346. int m; /* 应转移的键的数目 */    
  347. int i,j;    
  348. l = t->p[d];    
  349. r = t->p[d+1];    
  350.   
  351. m = (l->d - r->d)/2;    
  352. /* 把右子树中的所有键值和子树右移 m 个位置 */    
  353. r->p[r->d+m]=r->p[r->d];    
  354. for (i=r->d-1; i>=0; i--) {    
  355. r->k[i+m] = r->k;    
  356. r->v[i+m] = r->v;    
  357. r->p[i+m] = r->p;    
  358. }    
  359. /* 把这个键下移到它的右子树 */    
  360. r->k[m-1] = t->k[d];    
  361. r->v[m-1] = t->v[d];    
  362. /* 把左子树的最右子树转移成右子树的最左子树 */    
  363. r->p[m-1] = l->p[l->d];    
  364. /* 从左子树向右子树移动 m-1 个键+子树对 */    
  365. for (i=l->d-1,j=m-2; j>=0; j--,i--) {    
  366. r->k[j] = l->k;    
  367. r->v[j] = l->v;    
  368. r->p[j] = l->p;    
  369. }    
  370. /* 把左子树的最右键提升到这个键的位置上 */    
  371. t->k[d] = l->k;    
  372. t->v[d] = l->v;    
  373. l->d-=m;    
  374. r->d+=m;    
  375. }    
  376. /*   
  377. * 把一个键和对应的右子树从一个节点中删除   
  378. */    
  379. void DelFromNode(btree t, int d)    
  380. {    
  381. int i;    
  382. /* 把所有大于要删除的键值的键左移 */    
  383. for(i=d; i < t->d-1; i++) {    
  384. t->k = t->k[i+1];    
  385. t->v = t->v[i+1];    
  386. }    
  387. t->d--;    
  388. }    
  389. /*   
  390. * 建立有两个子树和一个键的根节点   
  391. */    
  392. btree NewRoot(btree t)    
  393. {    
  394. btree temp;    
  395. temp = (btree)malloc(sizeof(node));    
  396. temp->d = 1;    
  397. temp->p[0] = t;    
  398. temp->p[1] = NewTree;    
  399. temp->k[0] = InsKey;    
  400. temp->v[0] = InsValue;    
  401. btree_level++;    
  402. node_sum++;    
  403. return(temp);    
  404. }    
  405. /*   
  406. * 释放根节点,并返回它的最左子树   
  407. */    
  408. btree FreeRoot(btree t)    
  409. {    
  410. btree temp;    
  411. temp = t->p[0];    
  412. free(t);    
  413. btree_level--;    
  414. node_sum--;    
  415. return temp;    
  416. }    
  417.   
  418. void Error(int f,typekey key)    
  419. {    
  420. if (f)    
  421. printf("Btrees error: Insert %d! ",key);    
  422. else    
  423. printf("Btrees error: delete %d! ",key);    
  424. }    
  425.   
  426. int height(btree t)    
  427. {    
  428. return btree_level;    
  429. }    
  430.   
  431. int count(btree t)    
  432. {    
  433. return btree_count;    
  434. }    
  435. double payload(btree t)    
  436. {    
  437. if (node_sum==0)    
  438. return 1;    
  439. return (double)btree_count/(node_sum*(2*M));    
  440. }    
  441. btree deltree (btree t)    
  442. {    
  443. level=btree_level;    
  444. btree_level = 0;    
  445. return delall(t);    
  446.   
  447. }    
  448. btree delall(btree t)    
  449. {    
  450. int i;    
  451. level--;    
  452. if (level >= 0) {    
  453. for (i=0; i < t->d; i++)    
  454. if (t->v != NULL)    
  455. free(t->v);    
  456. if (level > 0)    
  457. for (i=0; i<= t->d ; i++)    
  458. t->p=delall(t->p);    
  459. free(t);    
  460. }    
  461. return NULL;    
  462. }    
  463.   
  464. /* end of btrees.c */   
3/3, 20«123»