笔记——二叉树

1、 二叉树的定义及特点

定义

定义:二叉树是树中节点数小于等于2的树

特点

1)在 k 层(即深度)中节点数<= 2 ^(k-1)
2)若最大层数为 k ,则树的总节点数<= 2^k-1(若为满二叉树则等于)
3)若叶节点个数:n0,度为2的节点数:n2,则 n2=n0-1

2、满二叉树与完全二叉树

满二叉树:除叶节点外,其余节点度数均为2

性质:若最大层数为 k ,则树的总节点数:2^k-1

完全二叉树:若树深度为K,则除第K层外其余层节点度数均=2,== 且第K层节点都集中在左边,依次排列==
在这里插入图片描述

3、二叉树存储结构(主要讲链式)

选择存储

用一组连续的存储单元存放二叉树中的结点。用编号的方法从树根起,自上层至下层,每层自左至右地给所有结点编号。

若为满二叉树或完全二叉树,则为最优选

在这里插入图片描述
在这里插入图片描述

链式存储

链表中每个结点由三个域组成,分别为:数据域和左右指针域。
在这里插入图片描述
在这里插入图片描述
定义节点

typedef struct node {
	int data;
	node *l;
	node *r;
} Tree;

创建树

void Create(node *&root) {
	int x;
	scanf("%d", &x);
	if (x == -1)
		root = NULL;
	else {
		root = (node *)malloc(sizeof(node));//分配空间
		root->data = x;//数据域赋值
		count++;//计算总节点数
//递归调用,给左右孩子节点赋值
		Create(root->l);
		Create(root->r);
	}
}

链式存储与顺序存储的优缺点

顺序存储

优点:存储密度大=1,存储空间利用概率高。
缺点:
(1)在顺序表中做插入、删除操作时,平均移动表中的一半元素,因此对n较大的顺序表效率低。
(2)需要预先分配足够大的存储空间,估计过大,可能会导致顺序表后部大量闲置;预先分配过小,又会造成溢出

链式存储

优点:插入、删除运算方便。
缺点:链表不是一种随机存储结构,不能随机存取元素。

适用情况

主要操作是查找,则采用顺序表;

主要操作是插入、删除操作,则采用链表。

4、树三种遍历方法

先序

void Preorder(Tree *root)
{
	if(NULL == root){
		return;
	}
	
	printf("%c ", root->data);//输出当前节点的数据
	//利用递归操作,先遍历完左子树,再遍历右子树
	Preorder_Tree(root->l);
	Preorder_Tree(root->r);
}

中序

void Mediate(Tree *root)
{
	if(NULL == root){
		return;
	}
	//先遍历左子树
	Mediate_Tree(root->l);
	printf("%c ", root->data);
	//再遍历右子树
	Mediate_Tree(root->r);
}

后序

void Post(Tree *root)
{
	if(NULL == root){
		return;
	}
	//先遍历左子树,再遍历右子树
	Post_Tree(root->l);
	Post_Tree(root->r);
	printf("%c ", root->data);
}

无视笔记在这里插入图片描述,笔记不对在这里插入图片描述

5、完整代码(增删查)

#include <stdio.h>
#include <stdlib.h>

//结点
typedef struct TreeNode {
	int value;
	struct TreeNode *left;
	struct TreeNode *right;
} TreeNode;
//创建树
TreeNode *createNode(int value) {
	TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
	if (!newNode) {
		printf("内存分配失败\n");
		exit(0);
	}
	newNode->value = value;
	newNode->left = NULL;
	newNode->right = NULL;
	return newNode;
}


//增
TreeNode *insertNode(TreeNode *root, int value) {
	if (root == NULL) {
		return createNode(value);
	}

	if (value < root->value) {
		root->left = insertNode(root->left, value);
	} else if (value > root->value) {
		root->right = insertNode(root->right, value);
	}

	return root;
}


//查
TreeNode *findNode(TreeNode *root, int value) {
	if (root == NULL || root->value == value) {
		return root;
	}

	if (value < root->value) {
		return findNode(root->left, value);
	} else {
		return findNode(root->right, value);
	}
}


//遍历
void inorderTraversal(TreeNode *root) {
	if (root == NULL) {
		return;
	}
	inorderTraversal(root->left);
	printf("%d ", root->value);
	inorderTraversal(root->right);
}


//删
TreeNode *deleteNode(TreeNode *root, int value) {
	if (root == NULL) {
		return root;
	}

	if (value < root->value) {
		root->left = deleteNode(root->left, value);
	} else if (value > root->value) {
		root->right = deleteNode(root->right, value);
	} else {
		if (root->left == NULL) {
			TreeNode *temp = root->right;
			free(root);
			root = temp;
		} else if (root->right == NULL) {
			TreeNode *temp = root->left;
			free(root);
			root = temp;
		} else {

			root->right = deleteNode(root->right, root->value);
		}
	}

	return root;
}



//----
int minValue(TreeNode *root) {
	int minValue = root->value;
	while (root->left != NULL) {
		minValue = root->left->value;
		root = root->left;
	}
	return minValue;
}

int main() {
	TreeNode *root = NULL;
	root = insertNode(root, 50);
	insertNode(root, 30);
	insertNode(root, 70);
	insertNode(root, 20);
	insertNode(root, 40);
	insertNode(root, 60);
	insertNode(root, 80);
	printf("中序遍历:");
	inorderTraversal(root);
	printf("\n查找元素 :40\n");
	TreeNode *node = findNode(root, 40);
	if (node != NULL) {
		printf("找到%d\n", node->value);
	} else {
		printf("未找到\n");
	}
	printf("\n删除元素:20\n剩余元素排序:");
	root = deleteNode(root, 20);
	inorderTraversal(root);
	return 0;
}

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值