数据结构与算法:二叉树

本文详细介绍了二叉树的概念,包括普通二叉树、满二叉树、完全二叉树和完美二叉树。同时,阐述了二叉树的四种遍历方法:前序遍历、中序遍历、后序遍历和层序遍历,并提供了递归和迭代两种实现方式。此外,还讲解了二叉树的插入操作和查找节点的方法。

二叉树

(一)二叉树

1.二叉树

在这里插入图片描述

(1)每个节点最多只有两个子节点


2.满二叉树

在这里插入图片描述

(1)每个节点只有0个或者2个子节点


3.完全二叉树

在这里插入图片描述

(1)每一层节点缺失的子节点只能在右边


4.完美二叉树
在这里插入图片描述

(1)每一层都是满节点


(二)二叉树遍历

1.递归

在这里插入图片描述

(1)递归退出条件

(2)何时递归


在这里插入图片描述

2.前序遍历:访问根节点,遍历左子树,遍历右子树

(1)递归法

void preOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	printf("%d ",root->data);
	preOrderRecTrav(root->left);
	preOrderRecTrav(root->right);
}

(2)迭代法

void preOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			v.push_back(root->data);
			s.push(root);
			root = root->left;
		}
		
		if(!s.empty())
		{
			root = s.top();
			s.pop();
			root = root->right;
		}
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
}

3.中序遍历:遍历左子树,访问根节点,遍历右子树

(1)递归法

void midOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	midOrderRecTrav(root->left);
	printf("%d ",root->data);
	midOrderRecTrav(root->right);
}

(2)迭代法

void midOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			s.push(root);
			root = root->left;
		}
		
		if(!s.empty())
		{
			root = s.top();
			v.push_back(root->data);
			s.pop();
			root = root->right;
		}
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
	
}

4.后续遍历:遍历左子树,遍历右子树,访问根节点

(1)递归法

void posOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	posOrderRecTrav(root->left);
	posOrderRecTrav(root->right);
	printf("%d ",root->data);
}

(2)迭代法

void posOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			v.push_back(root->data);
			s.push(root);
			root = root->right;
		}
		
		if(!s.empty())
		{
			root = s.top();
			s.pop();
			root = root->left;
		}
	}

	reverse(v.begin(),v.end());
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
	
}

5.层序遍历

void layOrderTrav(BinNode* root)
{
	queue<BinNode*> q;
	vector<Elem> v;
	
	q.push(root);

	while(root || !q.empty())
	{
		v.push_back(root->data);
		q.pop();
		if(root->left)
			q.push(root->left);
		if(root->right)
			q.push(root->right);
		
		root = q.front();
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
}

(三)二叉树操作

1.插入

2.遍历

#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>

#define Elem int

typedef struct BinNode {
	
	Elem data;
	struct BinNode* left;
	struct BinNode* right;
}BinNode;

BinNode* createNode(Elem data)
{
	BinNode* node = (BinNode*)malloc(sizeof(BinNode));
	
	node->data = data;
	node->left = NULL;
	node->right = NULL;
	
	return node;
}

BinNode* findNode(BinNode* root,Elem x)
{
	//中间变量,用于存放下层递归返回值
	BinNode* temp;
	
	if(root == NULL)
		return NULL;
	
	if(root->data == x)
		return root;
	
	temp = findNode(root->left,x);
	return temp?temp:findNode(root->right,x);
}

int insert(BinNode* root,Elem x,int LR,Elem data)
{
	int flag = 0;
	if(root == NULL)
		flag = -1;
	else
	{
		root = findNode(root,x);
		
		if(LR == 0)
		{
			if(root->left == NULL)
				root->left = createNode(data);
			else
				flag = -1;
		}
		else
		{
			if(root->right == NULL)
				root->right = createNode(data);
			else
				flag = -1;
		}
	}
		
	return flag;
}

void preOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	printf("%d ",root->data);
	preOrderRecTrav(root->left);
	preOrderRecTrav(root->right);
}

void midOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	midOrderRecTrav(root->left);
	printf("%d ",root->data);
	midOrderRecTrav(root->right);
}

void posOrderRecTrav(BinNode* root)
{
	if(root == NULL)
		return;
	posOrderRecTrav(root->left);
	posOrderRecTrav(root->right);
	printf("%d ",root->data);
}

void preOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			v.push_back(root->data);
			s.push(root);
			root = root->left;
		}
		
		if(!s.empty())
		{
			root = s.top();
			s.pop();
			root = root->right;
		}
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
}

void midOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			s.push(root);
			root = root->left;
		}
		
		if(!s.empty())
		{
			root = s.top();
			v.push_back(root->data);
			s.pop();
			root = root->right;
		}
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
	
}

void posOrderIterTrav(BinNode* root)
{
	stack<BinNode*> s;
	vector<Elem> v;
	
	while(root || !s.empty())
	{
		while(root)
		{
			v.push_back(root->data);
			s.push(root);
			root = root->right;
		}
		
		if(!s.empty())
		{
			root = s.top();
			s.pop();
			root = root->left;
		}
	}

	reverse(v.begin(),v.end());
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
	
}

void layOrderTrav(BinNode* root)
{
	queue<BinNode*> q;
	vector<Elem> v;
	
	q.push(root);

	while(root || !q.empty())
	{
		v.push_back(root->data);
		q.pop();
		if(root->left)
			q.push(root->left);
		if(root->right)
			q.push(root->right);
		
		root = q.front();
	}
	
	for(int i = 0;i < v.size();i++)
		cout << v.at(i) << " ";
}


int main()
{
   	/*  Write C code in this online editor and run it. */
	BinNode* root = createNode(0);
	
	insert(root,0,0,1);
	insert(root,0,1,2);
	insert(root,1,0,3);
	insert(root,1,1,4);
	insert(root,2,0,5);
	insert(root,2,1,6);
	insert(root,3,0,7);
	insert(root,3,1,8);
	insert(root,4,0,9);
	insert(root,4,1,10);
	insert(root,5,1,11);
	insert(root,6,0,12);
	
	cout << "递归遍历:"<<endl;
	preOrderRecTrav(root);
	cout <<endl;
	midOrderRecTrav(root);
	cout <<endl;
	posOrderRecTrav(root);
	cout <<endl<<endl<< "迭代遍历:"<<endl;
	preOrderIterTrav(root);
	cout <<endl;
	midOrderIterTrav(root);
	cout <<endl;
	posOrderIterTrav(root);
	cout <<endl<<endl<< "层序遍历:" <<endl;
	layOrderTrav(root);
   
   	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值