写在前面的话

最近接到几个大学同学研究生毕业不是签华为就是签百度,本人取经得到:操作系统、数据结构与算法、网络编程与数据库是面试中利器。想想自己工作2.5年月薪还不到10K,过着苦逼的码农生活,而他们一出校门就是大放光芒(最起码进入的公司就让人觉得牛逼哄哄的).本人痛定思痛,决定下大功夫学习一下数据结构与算法,我想这应该是根本吧.
之前也看过数据结构,但是一看到那乱七八糟的关系,就觉得还是研究一下别的东西,结果就是好多东西都是浅尝辄止,知子皮毛.
本人只贴出学习过程中的代码,以及一些发杂算法函数的详细注释,还有就是学习过程中遇到过的好的讲解URL,以供自己理解和后续的复习巩固,有不对的地方还需指正.

学习二叉树之前总感觉很抽象,最近看到亚嵌一个关于红黑树讲解的视频用到一个命令,能够将二叉树转换成图形打印出来,感觉很神奇,这个工具在Linux C编程一站式学习 中有提到过,
http://www.essex.ac.uk/linguistics/external/clmt/latex4ling/trees/tree/
有关应用会在后面代码测试中有提到,我想这应该是学习二叉树的一大利器,在此提出来。

源码

binarytree.h
#ifndef BINARYTREE_H
#define BINARYTREE_Htypedef struct node *link;
/***节点中的数据类型重定义*/
typedef unsigned char TElemType;struct node { TElemType item; link lchild, rchild;
};link init(TElemType VLR[], TElemType LVR[], int n);void pre_order(link t, void (*visit)(link));
void in_order(link t, void (*visit)(link));
void post_order(link t, void (*visit)(link));
void pprint(link t);
int count(link t);
int depth(link t);
void destroy(link t);/**
*http://www.cnblogs.com/bizhu/archive/2012/08/19/2646328.html 算法图解
*
*二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree),亦称二叉搜索树,
*它或者是一棵空树;或者是具有下列性质的二叉树:
*(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
*(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
*(3)左、右子树也分别为二叉排序树;
*(4)排序二叉树的中序遍历结果是从小到大排列的.
*
*二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低,为O(log n)。
*二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。
*
*搜索,插入,删除的复杂度等于树高,期望O(log n),最坏O(n)(数列有序,树退化成线性表)
*改进版的二叉查找树可以使树高为O(logn),如SBT,AVL,红黑树等.
*
*程序来源于Linux C编程一站式学习
*/
link bstSearch(link t, TElemType key);
link bstInsert(link t, TElemType key);
link bstDelete(link t, TElemType key);/***http://baike.baidu.com/view/593144.htm?fr=aladdin*平衡二叉树*/#endif

binarytree.c

/* binarytree.c */
#include <stdio.h>
#include <stdlib.h>
#include "binarytree.h"/***生成节点*@param item is node value*@returns link point to new node*/
static link make_node(TElemType item)
{link p = malloc(sizeof *p);p->item = item;p->lchild = p->rchild = NULL;return p;
}/***释放节点*@param link to free*/
static void free_node(link p)
{free(p);
}/***根据前序与中序序列来初始化二叉树*@param VLR 前序序列*@param LVR 中序序列*@param n 序列中数值个数*@returns NULL when n <= 0*@returns link pointer to new binarytree*/
link init(TElemType VLR[], TElemType LVR[], int n)
{link t;int k;if (n <= 0)return NULL;for (k = 0; VLR[0] != LVR[k]; k++);t = make_node(VLR[0]);t->lchild = init(VLR+1, LVR, k);t->rchild = init(VLR+1+k, LVR+1+k, n-k-1);return t;
}#ifdef RECU
/***前序遍历(跟左右)*@param t to visit*@param visit point to a func*/
void pre_order(link t, void (*visit)(link))
{if (!t)return;visit(t);pre_order(t->lchild, visit);pre_order(t->rchild, visit);
}/***中序序遍历(左跟右)*@param t to visit*@param visit point to a func*/
void in_order(link t, void (*visit)(link))
{if (!t)return;in_order(t->lchild, visit);visit(t);in_order(t->rchild, visit);
}/***中序序遍历(左右跟)*@param t to visit*@param visit point to a func*/
void post_order(link t, void (*visit)(link))
{if (!t)return;post_order(t->lchild, visit);post_order(t->rchild, visit);visit(t);
}
#endif/***遍历二叉树,生成用于tree工具的字符串*@param root to visit*/
void pprint(link root)
{printf("(");if (root != NULL) {printf("%d", root->item);pprint(root->lchild);pprint(root->rchild);}printf(")");
}int count(link t)
{if (!t)return 0;return 1 + count(t->lchild) + count(t->rchild);
}int depth(link t)
{int dl, dr;if (!t)return 0;dl = depth(t->lchild);dr = depth(t->rchild);return 1 + (dl > dr ? dl : dr);
}void destroy(link t)
{post_order(t, free_node);
}/***在bst中查找值为key的节点**1、若b是空树,则搜索失败,否则;*2、若x等于b的根节点的数据域之值,则查找成功;否则;*3、若x小于b的根节点的数据域之值,则搜索左子树;否则;*4、查找右子树.**@param t to search*@param key the value of link to find*@returns the link of the key*/
link bstSearch(link t, TElemType key)
{if (t == NULL)return NULL;if (t->item > key) {return bstSearch(t->lchild, key);} else if (t->item < key){return bstSearch(t->rchild, key);} else {return t;}
}/***在bst中插入值为key的节点**1、若t是空树,则将key作为根节点的值插入,否则;*2、若t->item大于key,则把key插入到左子树中,否则;*3、把key插入到左子树中.**@param t 要插入的 bst*@param key 要插入的值*@returns 插入后的bst*/
link bstInsert(link t, TElemType key)
{if (t == NULL) {return make_node(key);}if (t->item > key) {t->lchild = bstInsert(t->lchild, key);} else {t->rchild = bstInsert(t->rchild, key);}return t;
}/***在bst中删除值为key的节点**1、若t为空树,则直接返回NULL,否则;*2、若t->item大于key,bst左子树为bst左子树删除key后的bst,否则;*3、若t->item小于key,bst右子树为bst右子树删除key后的bst,否则;*4、若t->item == key:*       1.若其左右子树为NULL,返回NULL,即对其父节点赋值为NULL*     2.若其左子树不为NULL,则在其左子树中找到最大节点p,将p->item赋值给当前节点,还需要在其左子树中删除p->item,3.若其右子树不为NULL,则在其左子树中找到最小节点p,将p->item赋值给当前节点,还需要在其右子树中删除p->item,**@param t 要插入的 bst*@param key 要插入的值*@returns 插入后的bst*/
link bstDelete(link t, TElemType key)
{if (t == NULL)return NULL;if (t->item > key) t->lchild = bstDelete(t->lchild, key);else if (t->item < key)t->rchild = bstDelete(t->rchild, key);else {link p;if (t->lchild == NULL && t->rchild == NULL) {free_node(t);t = NULL;} else if (t->lchild){for (p = t->lchild; p->rchild; p = p->rchild);t->item = p->item;t->lchild = bstDelete(t->lchild, t->item);} else {for (p = t->rchild; p->lchild; p = p->lchild);t->item = p->item;t->rchild = bstDelete(t->rchild, t->item);}}return t;
}

测试程序

/* main.c */
#include <stdio.h>
#include <time.h>
#include "binarytree.h"#define RANGE      50
#define N       15void print_item(link p)
{printf("%d\t", p->item);
}void testBst()
{int i;link root = NULL;srand(time(NULL));for (i=0; i<N; i++)root = bstInsert(root, rand()%RANGE);printf("\\tree");pprint(root);printf("\n");TElemType key = rand() % RANGE;if (bstSearch(root, key)) {bstDelete(root, key);printf("\n%d\n", key);printf("\\tree");pprint(root);printf("\n");}
}void testInitByList()
{TElemType pre_seq[] = { 4, 2, 1, 3, 6, 5, 7 };TElemType in_seq[] = { 1, 2, 3, 4, 5, 6, 7 };link root = init(pre_seq, in_seq, 7);printf("\\tree");pprint(root);printf("\n");pre_order(root, print_item);putchar('\n');in_order(root, print_item);putchar('\n');post_order(root, print_item);putchar('\n');printf("count=%d depth=%d\n", count(root), depth(root));destroy(root);printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n\n");
}int main()
{//testInitByList();testBst();return 0;
}

对应的Makefie

#if you want to use recursive func,please make recu=y
ifeq (y, $(recu))CFLAGS += -DRECU
endififeq (y, $(debug))CFLAGS += -g
endifall:gcc $(CFLAGS) main.c binarytree.c binarytree.h -o treeclean:$(RM) tree

编译测试

在这里遍历二叉树只写了递归函数
在编译的时候用一下命令

make recu=y debug=y

运行结构如下:

\tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23(22()())(29()())))())(41()())))22
\tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23()(29()())))())(41()())))

好了接下来就是用工具tree,把这些字符串图形化

echo "\tree(15(6(0()())(7()(14(11(8()())())())))(41(36(18(16()())(23(22()())(29()())))())(41()())))" | tree -b2

怎么样这个效果。

把b2改成b6

二叉树学习之二叉查找树相关推荐

  1. 二叉树学习之二叉查找树 http://blog.csdn.net/callinglove/article/details/40707449

    二叉树学习之二叉查找树 标签: 二叉树二叉树图形化二叉查找树二叉树递归遍历 2014-11-02 10:49  1441人阅读  评论(0)  收藏  举报   分类: ACM&算法(8)  ...

  2. 二叉树学习笔记(未完待续)

    摘要 二叉树学习笔记(未完待续). 博客 IT老兵驿站. 前言 昨天(2019-11-07)复习红黑树,发现红黑树和二叉树密不可分,所以这里再复习一下二叉树. 在大学的时候,这块我很认真地学习了一遍. ...

  3. “树与二叉树”学习提纲

    文章目录 前言 树的基本概念 树的关键概念 树的存储结构 树的常用性质 二叉树的概念 二叉树的基本形态 特殊的二叉树 二叉树的性质 二叉树的存储结构 二叉树的遍历和线索二叉树 二叉树的遍历方式 二叉树 ...

  4. 新手学习算法----二叉树(将一个二叉查找树按照中序遍历转换成双向链表)

    题目:将一个二叉查找树按照中序遍历转换成双向链表. 给定一个二叉查找树: 4/ \2 5/ \ 1 3 返回 1<->2<->3<->4<->5. 思路 ...

  5. 二叉树学习之非递归遍历

    二叉树递归遍历可谓是学过数据结构的同仁都能想一下就能写出来,但在应聘过程我们常常遇到的是写出一个二叉树非递归遍历函数,接着上篇文章写二叉树的非递归遍历,先难后易,一步一步的来. 先上代码: #incl ...

  6. 二叉树学习笔记之树的旋转

    树旋转(Tree rotation)是二叉树中的一种子树调整操作,每一次旋转并不影响对该二叉树进行中序遍历的结果. 树旋转通常应用于需要调整树的局部平衡性的场合. 左旋和右旋 树的旋转有两种基本的操作 ...

  7. 学习数据结构 二叉查找树(binary search tree)

    2019独角兽企业重金招聘Python工程师标准>>> 为学习 LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树(平衡二叉搜索树),我不很熟悉该树,虽然大致知道 ...

  8. 二叉树学习的一些个人心得

    目录 前言 二叉树的种类 满二叉树 完全二叉树 二叉搜索树 平衡二叉搜索树 二叉树的存储方式 二叉树的遍历方式 二叉树的代码描述 总结 参考文献 前言 开启算法新征程,为了让我对二叉树有新层次的理解, ...

  9. 二叉树(BT)、二叉查找树(BST)、平衡二叉树(AVL)、B-Tree、B+Tree、红黑树(BRT)

    目录 树的概念 树的分类 二叉树 二叉查找树 平衡二叉树(AVL) B-Tree(平衡多路查找树) B树的关键特征 B+Tree B+树关键特征 红黑树(BRT) 左旋 右旋 时间复杂度 树形结构是一 ...

最新文章

  1. 真的,千万不要给女朋友解释 什么是 “羊群效应”
  2. 硬分叉升级加速BCH相关应用研发
  3. 必须对手机内置业务制定规范防止后门
  4. apt-get remove 与 apt-get purge 区别(删除包、卸载包)
  5. python封装方法有几种_Python打包exe文件方法汇总【4种】
  6. html语言循环语句,Scala @功能/语言的HTML文档 - for循环,如果语句等
  7. php公司面试反问,php面试坑集锦
  8. R6饮料AK赛(NOIP模拟赛)/省选专练HDU 5713 K个联通块
  9. ospf配置命令_思科设备 OSPF 的相关知识点
  10. spring mvc实例
  11. 如何在Eclipse 3.6.2中安装swt/JFace
  12. python机器学习:朴素贝叶斯分类算法
  13. docker 升级linux内核,docker-machine之升级linux内核
  14. 【黑马-SpringCloudAlibaba】学习笔记09-Nacos Config--服务配置
  15. python123新版个人所得税计算请输入正数_Python训练的数字组合,个人所得税计算,完全平方数,python,之...
  16. 20162307张韵琪 预备作业02
  17. HR常问到的TopK问题解决办法
  18. XDOJ.172 构造表达式
  19. 牛客wannafly27 C 树形dp
  20. C语言答疑合集(一)

热门文章

  1. mysql分列查询,Mysql导出问题,乱码问题,为分列问题解决!!!
  2. 奖品兑现 – 我家没有好茶饭,只有《编程之美》送亲人
  3. 硬盘突然提示没有初始化_新硬盘的分区
  4. 机器人的自述作文_机器人的自述作文600字
  5. php属性未定义,PHP-警告-未定义的属性:stdClass-修复?
  6. 牙齿间隙变大怎么办_牙齿之间的间隙越来越大怎么办?
  7. python mysql 保存csv_使用Python将csv文件快速转存到Mysql
  8. linux相关英文书记,Linux常用软件(英文介绍)
  9. pytorch模型加载测试_pytorch模型加载方法汇总
  10. pythonui自动化测试平台_django+appium实现UI自动化测试平台(开源部分,可定制开发)...