前不久去腾讯笔试,居然几道数据结构方面的题目,让我情何以堪啊,都做不动,忘完了,趁着这里想找实习的地方,肯定还要笔试,所以复习一下。

注意:函数指针传递的用法

1.二叉树重要性质:

性质1:在二叉树的第i层上至多有2^(i-1)个节点(i >= 1)

性质2:深度为k的二叉树至多有2^(k-1)个节点(k >=1)

性质3:对于任意一棵二叉树T而言,其叶子节点数目为N0,度为2的节点数目为N2,则有

N0 = N2 + 1。

2. 二叉树的遍历

(1)前序遍历:先访问根节点,然后先序遍历左子树,最后先序遍历右子树;

(2)中序遍历:先序遍历左子树,然后访问根节点,最后先序遍历右子树;

(3)后序遍历:先序遍历左子树,然后先序遍历右子树,最后访问根节点;

假如有如下二叉树:

前序遍历:ABDHEICFGJ

中序遍历:HDBEIAFCGJ

后序遍历:HDIEBFJGCA

递归遍历具体实现代码:

void PreOrder(BTree T)

{

if(T)

{

PrintNode(T);

PreOrder(T->l);

PreOrder(T->r);

}

}

void MidOrder(BTree T)

{

if(T)

{

MidOrder(T->l);

PrintNode(T);

MidOrder(T->r);

}

}

void BehOrder(BTree T)

{

if(T)

{

BehOrder(T->l);

BehOrder(T->r);

PrintNode(T);

}

}

3. 二叉树存储结构设计:我们设计左子树的项目比根节点小

typedef struct item

{

int key;

}Item;

typedef  struct  BiNode

{

Item item;

int count;

struct  BiNode  *l;

struct  BiNode  *r;

}BNode, *PBNode, *BTree;  // struct  BiNode =Bnode

设计树的节点为结构体是为了以后扩展树节点做铺垫,设计PBNode表示节点指针,设计Btree树的结构。

4. 递归生成二叉树:compare()函数是比较两个节点之间项目大小的函数,这里以及后面的函数大都设计为参数为指针传递,因为指针大小一般比值参数小,所以这样设计可以节约栈空间,使用const关键字来修饰不变的变量从而增强程序的健壮性。

int compare(const Item *item1, const Item *item2)

{

if(item1->key < item2->key)

return -1;

else if(item1->key == item2->key)

return 0;

else

return 1;

}

BTree Create(BTree T, const Item *item)

{

if(T == NULL)

{

if(!(T=(PBNode)malloc(sizeof(BNode)))) //一定是结构体类

perror("malloc error!");

T->item = *item;

T->count = 1;

T->l = NULL;

T->r = NULL;

}

else if(compare(&(T->item), item) == 1)

{

T->l = Create(T->l, item);

}

else if(compare(&(T->item), item) == 0)

{

T->count ++;

}

else

T->r = Create(T->r, item);

return T;

}

5. 设计树深度的函数和查找最大项节点,最小项节点函数

int Height(BTree T)

{

int h1, h2;

if(T == NULL)

{

return 0;

}

else

{

h1 = Height(T->l);

h2 = Height(T->r);

return  max(h1,h2)+1;       //函数也可以不再main 中声名而直接调用

}

}

PBNode FindMax(BTree T)

{

if(T->r == NULL)

return T;

else return FindMax(T->r);

}

PBNode FindMin(BTree T)

{

if(T->l == NULL)

return T;

else return FindMin(T->l);

}

6. 删除单节点函数

设计删除单节点函数时需要考虑两点:

(1) 删除的点为根节点:如果右子树为空,则直接将左子树的根节点直接设置为整棵树的根节点;如果非空,则把左子树挂载右子树最小项的左子树上。

情况1示例如下:

如果要删除根节点,则直接将左子树的根节点直接设置为整棵树的根节点,并且更新根节点。

情况2示例如下:

如果要删除根节点,则把左子树挂载右子树最左项即右子树最小值的左子树上,并且更新根节点。

(2) 删除节点不为根节点:找到需要删除的点的父节点,如果删除节点的右子树为空则直接将删除节点的子树挂载他的父节点上;如果删除节点的右子树不为空,则将删除节点的左子树挂载到右子树的最小项上,并把右子树挂在删除节点的父节点上面。

情况1示例如下:

需要删除节点值为3的节点,因为没有右子树,则直接将删除节点的子树挂载他的父节点上。

情况2示例如下:

需要删除节点值为3的节点,因为有右子树,则将删除节点的左子树挂载到右子树的最小项上,并把右子树挂在删除节点的父节点上面。

BTree DeteleNode(BTree T, const Item *item)

{

PBNode fnode = NULL;

PBNode node = NULL, temp = NULL;

int dir = 0;

node = FindNode(T, item);//查找符合条件节点

if(node == T)//如果删除的点为根节点

{

printf("root delete \n");

fnode = FindMin(T->r);//找到根节点右子树最小值

if(fnode == NULL)//如果右子树为空 则将左子树直接设为根节点

{

return node->l;

}

fnode->l = node->l;

fnode = node->r;

free(node);

return fnode;//注意返回最新的根节点的指针

}

else if(node == NULL)

{

printf("not find the item\n");

}

else

{

fnode = FindFNode(T, node, &dir);

//方向1 代表左子树 2代表右子树

if(node->r == NULL)

{

if(dir == 1)

{

fnode->l = node->l;

}

else

{

fnode->r = node->l;

}

}

else

{

if(dir == 1)

{

fnode->l = node->r;

node->r->l = node->l;

}

else

{

fnode->r = node->r;

node->r->l = node->l;

}

}

free(node);

return T;

}

}

7. 实现二叉树所有代码如下:

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <errno.h>

#define max(a,b) a>b ? a : b

#define min(a,b) a<b ? a : b

typedef struct item

{

int key;

}Item;

typedef  struct  BiNode

{

Item item;

int count;

struct  BiNode  *l;

struct  BiNode  *r;

}BNode, *PBNode, *BTree;  // struct  BiNode =BNode

int compare(const Item *item1, const Item *item2)

{

if(item1->key < item2->key)

return -1;

else if(item1->key == item2->key)

return 0;

else

return 1;

}

BTree Create(BTree T, const Item *item)

{

if(T == NULL)

{

if(!(T=(PBNode)malloc(sizeof(BNode)))) //一定是结构体类

perror("malloc error!");

T->item = *item;

T->count = 1;

T->l = NULL;

T->r = NULL;

}

else if(compare(&(T->item), item) == 1)

{

T->l = Create(T->l, item);

}

else if(compare(&(T->item), item) == 0)

{

T->count ++;

}

else

T->r = Create(T->r, item);

return T;

}

void PrintItem(const Item * const item)

{

printf("key = %d ", item->key);

}

void PrintNode(const PBNode node)

{

PrintItem(&node->item);

printf("count is %d\n", node->count);

}

void PreOrder(BTree T)

{

if(T)

{

PrintNode(T);

PreOrder(T->l);

PreOrder(T->r);

}

}

void MidOrder(BTree T)

{

if(T)

{

MidOrder(T->l);

PrintNode(T);

MidOrder(T->r);

}

}

void BehOrder(BTree T)

{

if(T)

{

BehOrder(T->l);

BehOrder(T->r);

PrintNode(T);

}

}

int Height(BTree T)

{

int h1, h2;

if(T == NULL)

{

return 0;

}

else

{

h1 = Height(T->l);

h2 = Height(T->r);

return  max(h1,h2)+1;       //函数也可以不再main 中声名而直接调用

}

}

PBNode FindMax(BTree T)

{

if(T->r == NULL)

return T;

else return FindMax(T->r);

}

PBNode FindMin(BTree T)

{

if(T->l == NULL)

return T;

else return FindMin(T->l);

}

PBNode FindNode(const BTree T, const Item *item)

{

if(T)

{

if(compare(&T->item, item) == 0 )

{

return T;

}

else if (compare(&T->item, item) == 1 )

{

return FindNode(T->l, item);

}

else

return  FindNode(T->r, item);

}

return NULL;

}

PBNode FindFNode(const BTree T, const PBNode node, int *dir)

{

PBNode my;

if(T->l == node)

{

*dir = 1;

return T;

}

else if(T->r == node)

{

*dir = 2;

return T;

}

else

{

my = FindFNode(T->l, node, dir);

if(my == NULL)

return FindFNode(T->r, node, dir);

else

return my;

}

return NULL;

}

BTree DeteleNode(BTree T, const Item *item)

{

PBNode fnode = NULL;

PBNode node = NULL, temp = NULL;

int dir = 0;

node = FindNode(T, item);

if(node == T)

{

printf("root delete \n");

fnode = FindMin(T->r);

if(fnode == NULL)

{

return node->l;

}

fnode->l = node->l;

fnode = node->r;

free(node);

return fnode;

}

else if(node == NULL)

{

printf("not find the item\n");

}

else

{

fnode = FindFNode(T, node, &dir);

//方向1 代表左子树 2代表右子树

if(node->r == NULL)

{

if(dir == 1)

{

fnode->l = node->l;

}

else

{

fnode->r = node->l;

}

}

else

{

if(dir == 1)

{

fnode->l = node->r;

node->r->l = node->l;

}

else

{

fnode->r = node->r;

node->r->l = node->l;

}

}

free(node);

return T;

}

}

void DeleteAll(BTree *T)

{

if(*T)

{

if((*T)->l == NULL && (*T)->r == NULL)

{

free(*T);

*T = NULL;

return ;

}

if((*T)->l != NULL)

DeleteAll(&(*T)->l);

if((*T)->r != NULL)

DeleteAll(&(*T)->r);

}

return ;

}

void DeleteAll(BTree T)

{

if(T)

{

if((T)->l == NULL && (T)->r == NULL)

{

free(T);

return ;

}

if(T->l != NULL)

DeleteAll(T->l);

if(T->r != NULL)

DeleteAll(T->r);

}

return ;

}

static void DeleteAllNodes(BTree T)

{

PBNode pright;

if(T != NULL)

{

pright = T->r;

DeleteAllNodes(T->l);

free(T);

DeleteAllNodes(pright);

}

}

int main(void)

{

int tHeight,b,x;

Item item;

PBNode node = NULL;

BTree  t = NULL;

int chose = 0;

while(1)

{

printf("1.create tree(-1 exit)\n");

printf("2.preorder travser\n");

printf("3.miderorder travser\n");

printf("4.beherorder travser\n");

printf("5.tree height\n");

printf("6.find key = x:\n");

printf("7.delete key = x\n");

printf("8.delete all\n");

printf("9.find min and max\n");

printf("0.exit\n");

scanf("%d", &chose);

switch(chose)

{

case 1:

while(1)

{

scanf("%d", &(item.key));

if(item.key == -1)

break;

t=Create(t,&item);  //也用递归 创建

}

break;

case 2:

PreOrder(t);

printf("\n");

break;

case 3:

MidOrder(t);

printf("\n");

break;

case 4:

BehOrder(t);

printf("\n");

break;

case 5:

tHeight = Height(t);

printf("\n tree height is %d\n",tHeight);

break;

case 6:

printf("\ninput the x to find :");

scanf("%d",&x );

item.key = x;

node = FindNode(t,&item);

if(node == NULL)

printf("not find \n");

else

{

PrintNode(node);

}

printf("\n");

break;

case 7:

printf("\ninput the x to delete:");

scanf("%d",&x );

item.key = x;

node = FindNode(t,&item);

if(node == NULL)

printf("not find \n");

else

{

PrintNode(node);

t = DeteleNode(t, &item);

}

printf("\n");

break;

case 8:

// DeleteAll(&t);

DeleteAllNodes(t);

// DeleteAll(t);

t = NULL;

break;

case 9:

node = FindMax(t);

PrintNode(node);

node = FindMin(t);

PrintNode(node);

break;

case 0:

break;

}

if(chose == 0)

break;

}

return 0;

}

数据结构之查找二叉树相关推荐

  1. 【算法与数据结构】查找二叉树的实现

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 1.题目介绍     二叉树是一种基本的数据结构.查找二叉树是一种方便与查找,删除,插入等功能的二叉树,它要求每 ...

  2. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  3. 数据结构与算法 | 二叉树的实现

    前几章实现了二叉树的顺序结构和二叉树的几种遍历,这次就来实现二叉树的链式结构 数据结构 typedef char BTDataType; typedef struct BTNode {BTDataTy ...

  4. 数据结构与算法--二叉树第k个大的节点

    二叉树第k个大的节点 二叉树文章列表: 数据结构与算法–面试必问AVL树原理及实现 数据结构与算法–二叉树的深度问题 数据结构与算法–二叉堆(最大堆,最小堆)实现及原理 数据结构与算法–二叉查找树转顺 ...

  5. 数据结构与算法-- 二叉树中和为某一值的路径

    二叉树中和为某一值的路径 题目:输入一颗二叉树和一个整数,打印出二叉树中节点值的和为给定值的所有路径.从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径. 我们用二叉树节点的定义沿用之前文章中 ...

  6. 数据结构与算法——二叉树、堆、优先队列

    *************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 七 ...

  7. 以下哪种数据结构的查找效率最高

    网易2017实习生招聘笔试题-Java开发工程师 以下哪种数据结构的查找效率最高 A 二叉树 B 队列 C 栈 D hash 个人参考答案:D 欢迎下方讨论交流

  8. 查找二叉树(BST)

    1.查找二叉树的定义 先上图: 一棵二叉搜索树(Binary Sort Tree)是以一棵二叉树来组织的,可以用链表数据结构来表示,其中,每一个结点就是一个对象,一般地,包含数据值和指向孩子(也可能是 ...

  9. 【数据结构复习】二叉树的遍历——从微软2014校园招聘说起

    [数据结构复习]是学习.复习常用数据结构系列文章.数据结构与算法密不可分,是程序实现功能的重要组成部分.优秀的数据结构可以提高算法的时间及空间效率.反之,将增加算法复杂度,甚至妨碍程序的正确执行. 一 ...

最新文章

  1. 【算法学习笔记】08.数据结构基础 二叉树初步练习1
  2. Android进阶:六、在子线程中直接使用 Toast 及其原理
  3. iOS下KVO使用过程中的陷阱
  4. fabric sdk php,基于 Fabric-SDK-Go 的Web项目实战之使用Fabric-SDK-Go满足依赖
  5. springboot pom文件指定jdk_Spring Boot 入门
  6. Factory Method工厂方法
  7. 查找空目录Linux,Linux中find批量删除空文件及空文件夹脚本
  8. Vue.js中data,props和computed数据
  9. Pytorch+Tensorboard混淆矩阵可视化
  10. hbuilderx制作简单网页_简单的手机网页制作教程
  11. .net api reference中文_在macOS上使用.NET SDK编译 .NET 通用中间语言
  12. ROS学习笔记6(理解ROS话题)
  13. asc码转换 linux_Linux网络服务04——FTP文件传输服务
  14. 天然气压缩因子计算软件_测量天然气用什么流量计?
  15. IOS开发-我的第一个IOS程序
  16. 使用$.post和action或servlet交互 URL出现 http://localhost:8080/../[object%20Object] 错误的问题解决
  17. 数据结构笔记(二十六)-- 图的存储
  18. AppFuse 3的乱码问题
  19. Oracle数据库的安装
  20. 计算机网络专业运动会入场式,高校运动会方阵入场式花样百出

热门文章

  1. 【OpenGL】十三、OpenGL 绘制三角形 ( 绘制单个三角形 | 三角形绘制顺序 | 绘制多个三角形 )
  2. VS2013试用期结束后如何激活
  3. 小技巧textbox的行数
  4. Go -- pprof协程监控
  5. CCBPM高级开发之类设计与数据库设计命名规则
  6. 升级GCC 4.6后的warning: ”variable set but not used“
  7. Enterprise Library 4.1 Application Settings 快速使用图文笔记
  8. LeetCode算法题13:DFS/BFS - 单词搜索
  9. 纯CSS实现Tab栏的切换
  10. PowerShell导出共存环境下的Exchange数据库列表