C++实现二叉树(转)
/*************************************************************************
这是一个二叉查找树,实现了以下操作:插入结点、构造二叉树、删除结点、查找、
查找最大值、查找最小值、查找指定结点的前驱和后继。上述所有操作时间复杂度
均为o(h),其中h是树的高度
注释很详细,具体内容就看代码吧
*************************************************************************/
#include<stdio.h>
#include<stdlib.h>
//二叉查找树结点描述
typedef int KeyType;
typedef struct Node
{
KeyType key; //关键字
struct Node * left; //左孩子指针
struct Node * right; //右孩子指针
struct Node * parent; //指向父节点指针
}Node,*PNode;
//往二叉查找树中插入结点
//插入的话,可能要改变根结点的地址,所以传的是二级指针
void inseart(PNode * root,KeyType key)
{
//初始化插入结点
PNode p=(PNode)malloc(sizeof(Node));
p->key=key;
p->left=p->right=p->parent=NULL;
//空树时,直接作为根结点
if((*root)==NULL){
*root=p;
return;
}
//插入到当前结点(*root)的左孩子
if((*root)->left == NULL && (*root)->key > key){
p->parent=(*root);
(*root)->left=p;
return;
}
//插入到当前结点(*root)的右孩子
if((*root)->right == NULL && (*root)->key < key){
p->parent=(*root);
(*root)->right=p;
return;
}
if((*root)->key > key)
inseart(&(*root)->left,key);
else if((*root)->key < key)
inseart(&(*root)->right,key);
else
return;
}
//查找元素,找到返回关键字的结点指针,没找到返回NULL
PNode search(PNode root,KeyType key)
{
if(root == NULL)
return NULL;
if(key > root->key) //查找右子树
return search(root->right,key);
else if(key < root->key) //查找左子树
return search(root->left,key);
else
return root;
}
//查找最小关键字,空树时返回NULL
PNode searchMin(PNode root)
{
if(root == NULL)
return NULL;
if(root->left == NULL)
return root;
else //一直往左孩子找,直到没有左孩子的结点
return searchMin(root->left);
}
//查找最大关键字,空树时返回NULL
PNode searchMax(PNode root)
{
if(root == NULL)
return NULL;
if(root->right == NULL)
return root;
else //一直往右孩子找,直到没有右孩子的结点
return searchMax(root->right);
}
//查找某个结点的前驱
PNode searchPredecessor(PNode p)
{
//空树
if(p==NULL)
return p;
//有左子树、左子树中最大的那个
if(p->left)
return searchMax(p->left);
//无左子树,查找某个结点的右子树遍历完了
else{
if(p->parent == NULL)
return NULL;
//向上寻找前驱
while(p){
if(p->parent->right == p)
break;
p=p->parent;
}
return p->parent;
}
}
//查找某个结点的后继
PNode searchSuccessor(PNode p)
{
//空树
if(p==NULL)
return p;
//有右子树、右子树中最小的那个
if(p->right)
return searchMin(p->right);
//无右子树,查找某个结点的左子树遍历完了
else{
if(p->parent == NULL)
return NULL;
//向上寻找后继
while(p){
if(p->parent->left == p)
break;
p=p->parent;
}
return p->parent;
}
}
//根据关键字删除某个结点,删除成功返回1,否则返回0
//如果把根结点删掉,那么要改变根结点的地址,所以传二级指针
int deleteNode(PNode* root,KeyType key)
{
PNode q;
//查找到要删除的结点
PNode p=search(*root,key);
KeyType temp; //暂存后继结点的值
//没查到此关键字
if(!p)
return 0;
//1.被删结点是叶子结点,直接删除
if(p->left == NULL && p->right == NULL){
//只有一个元素,删完之后变成一颗空树
if(p->parent == NULL){
free(p);
(*root)=NULL;
}else{
//删除的结点是父节点的左孩子
if(p->parent->left == p)
p->parent->left=NULL;
else //删除的结点是父节点的右孩子
p->parent->right=NULL;
free(p);
}
}
//2.被删结点只有左子树
else if(p->left && !(p->right)){
p->left->parent=p->parent;
//如果删除是父结点,要改变父节点指针
if(p->parent == NULL)
*root=p->left;
//删除的结点是父节点的左孩子
else if(p->parent->left == p)
p->parent->left=p->left;
else //删除的结点是父节点的右孩子
p->parent->right=p->left;
free(p);
}
//3.被删结点只有右孩子
else if(p->right && !(p->left)){
p->right->parent=p->parent;
//如果删除是父结点,要改变父节点指针
if(p->parent == NULL)
*root=p->right;
//删除的结点是父节点的左孩子
else if(p->parent->left == p)
p->parent->left=p->right;
else //删除的结点是父节点的右孩子
p->parent->right=p->right;
free(p);
}
//4.被删除的结点既有左孩子,又有右孩子
//该结点的后继结点肯定无左子树(参考上面查找后继结点函数)
//删掉后继结点,后继结点的值代替该结点
else{
//找到要删除结点的后继
q=searchSuccessor(p);
temp=q->key;
//删除后继结点
deleteNode(root,q->key);
p->key=temp;
}
return 1;
}
//创建一棵二叉查找树
void create(PNode* root,KeyType *keyArray,int length)
{
int i;
//逐个结点插入二叉树中
for(i=0;i<length;i++)
inseart(root,keyArray[i]);
}
int main(void)
{
int i;
PNode root=NULL;
KeyType nodeArray[11]={15,6,18,3,7,17,20,2,4,13,9};
create(&root,nodeArray,11);
for(i=0;i<2;i++)
deleteNode(&root,nodeArray[i]);
printf("%d\n",searchPredecessor(root)->key);
printf("%d\n",searchSuccessor(root)->key);
printf("%d\n",searchMin(root)->key);
printf("%d\n",searchMax(root)->key);
printf("%d\n",search(root,13)->key);
return 0;
}
C++实现二叉树(转)的更多相关文章
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 二叉树的递归实现(java)
这里演示的二叉树为3层. 递归实现,先构造出一个root节点,先判断左子节点是否为空,为空则构造左子节点,否则进入下一步判断右子节点是否为空,为空则构造右子节点. 利用层数控制迭代次数. 依次递归第二 ...
- c 二叉树的使用
简单的通过一个寻找嫌疑人的小程序 来演示二叉树的使用 #include <stdio.h> #include <stdlib.h> #include <string.h& ...
- Java 二叉树遍历右视图-LeetCode199
题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...
- 数据结构:二叉树 基于list实现(python版)
基于python的list实现二叉树 #!/usr/bin/env python # -*- coding:utf-8 -*- class BinTreeValueError(ValueError): ...
- [LeetCode] Path Sum III 二叉树的路径和之三
You are given a binary tree in which each node contains an integer value. Find the number of paths t ...
- [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点
Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...
- [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化
One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...
- [LeetCode] Binary Tree Vertical Order Traversal 二叉树的竖直遍历
Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...
- [LeetCode] Binary Tree Longest Consecutive Sequence 二叉树最长连续序列
Given a binary tree, find the length of the longest consecutive sequence path. The path refers to an ...
随机推荐
- 编译u-boot命令和u-boot常用命令
一.编译u-boot命令 1.配置开发板 #make TQ2440_config 2.编译 #make all 3.交叉编译器是crosstools_3.4.5_softfloat” 使用4.3.3版 ...
- CentOS 6.0 图文安装教程
CentOS 6.0下载地址:wget http://ftp.riken.jp/Linux/centos/6.0/isos/i386/CentOS-6.0-i386-bin-DVD.iso 下边就是安 ...
- [BZOJ 3282] Tree 【LCT】
题目链接:BZOJ - 3282 题目分析 这道题是裸的LCT,包含 Link , Cut 和询问两点之间的路径信息. 写代码时出现的错误:Access(x) 的循环中应该切断的是原来的 Son[x] ...
- 【NOIP 2011】 观光公交
题目描述 Description 风景迷人的小城 Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0 分钟出现在1号 ...
- uva 10496 Collecting Beepers
一个简单的货郎担问题,用状态压缩dp可以解决: 解法: d(i,S)=min{d(j,S-{j})+dis(i,j) | j belongs to S}; 边界条件:d(i,{})=dis(0,i). ...
- JPA2.1 中三个提升应用性能的新功能
经常在网上看到开发者们抱怨 JPA 性能低下的帖子或文章,但如果仔细查看这些性能问题,常会发现导致问题的根本原因大致包括以下几个: 使用过多的 SQL 查询从数据库中获取所需的实体信息,即我们常说的n ...
- Katu Puzzle
poj3678:http://poj.org/problem?id=3678 题意:给你一些数,然后这些要么是0要么是1,然后回给出一些数之间的and,or,xor的值,问你是否存在一组解. 题解:2 ...
- Delphi常用排序
1.冒泡排序 Delphi/Pascal code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 procedure BubbleSort(var x:a ...
- Android开源项目发现--- 工具类图片缓存篇(持续更新)
1. Android-Universal-Image-Loader 图片缓存 目前使用最广泛的图片缓存,支持主流图片缓存的绝大多数特性. 项目地址:https://github.com/nostra1 ...
- 内存管理(memory allocation内存分配)
Memory management is the act of managing computer memory. The essential requirement of memory manage ...