数据结构与算法-二叉树

树形结构

(一)二叉树

1.满二叉树:每个节点要么有两个子节点要么没有(要么没有孩子,有就有两个)

2.完全二叉树:只要有一层节点不是满节点,空节点的位置只能是右边的节点没有孩子

3.完美二叉树:每一层的节点都是满的,没有一个空位置

性能(时间复杂度):链表 < 普通二叉树 < 满二叉树 < 完全二叉树 < 完美二叉树


(二)编程实现

1.二叉树节点的创建

2.二叉树的遍历

(1)递归遍历:前、中、后序

  • 可能出现栈溢出

(2)迭代遍历:前、中、后序、层序

  • 用软件栈实现硬件栈功能,可以防止栈溢出

3.二叉树的查找与插入


C++实现

#include <iostream>
#include <stack>
#include <queue>

using namespace std;



template<class Elem>
struct BinNode{

	Elem data;
	BinNode<Elem>* left;
	BinNode<Elem>* right;
	BinNode(Elem x){
	
		data = x;
		left = right = NULL;
		
	}
	
};

template<class Elem>
class BinTree{
	
	public:
		BinNode<Elem>* root;
		
		void pre(BinNode<Elem>* root);
		void ipre(BinNode<Elem>* root);
		
		void mid(BinNode<Elem>* root);
		void imid(BinNode<Elem>* root);
		
		void pos(BinNode<Elem>* root);
		void ipos(BinNode<Elem>* root);
		
		void lay(BinNode<Elem>* root);
		
		BinNode<Elem>* find(Elem p,BinNode<Elem>* root);
	public:
		BinTree(){ root = NULL; };
		BinTree(Elem x){
			
			root = new BinNode<Elem>(x);
		}
		~BinTree(){}
		
		void preOrderTraversal();
		void midOrderTraversal();
		void posOrderTraversal();
		void layOrderTraversal();
		bool insert(Elem p,int LR,int data);
};

//前序递归:递和归(有去有回)
template<class Elem>
void BinTree<Elem>::pre(BinNode<Elem>* root){
	
	if(root == NULL)
		return;
	cout << root->data << " ";
	pre(root->left);
	pre(root->right);
}

//前序迭代(用栈数据结构实现):按顺序入栈,直到走不通出栈(入栈、出栈顺序按照前序方式)
template<class Elem>
void BinTree<Elem>::ipre(BinNode<Elem>* root) {

	stack<BinNode<Elem>*> st;
	
	while(root)
	{
		cout << root->data << " ";
		st.push(root);
		root = root->left;
		
		//不断判断节点是否为空(节点访问到头,回到前一个节点再判断)
		while(root == NULL && !st.empty())
		{
			root = st.top();
			st.pop();
			root = root->right;
		}
	}
}

//前序遍历
template<class Elem>
void BinTree<Elem>::preOrderTraversal(){

	cout << "1.递归方法:";
	pre(root);
	cout <<endl;
	cout << "2.迭代方法:";
	ipre(root);
}

//中序递归
template<class Elem>
void BinTree<Elem>::mid(BinNode<Elem>* root){

	if(root == NULL)
		return;
	mid(root->left);
	cout << root->data << " ";
	mid(root->right);

}

//中序迭代
template<class Elem>
void BinTree<Elem>::imid(BinNode<Elem>* root){
	
	stack<BinNode<Elem>*> st;
	
	while(root)
	{
		st.push(root);
		root = root->left;
		while(root == NULL && !st.empty())
		{
			root = st.top();
			st.pop();
			cout << root->data <<" ";
			root = root->right;
		}
	}

}

//中序遍历
template<class Elem>
void BinTree<Elem>::midOrderTraversal(){
	cout << "1.递归方法:";
	mid(root);
	cout <<endl;
	cout << "2.迭代方法:";
	imid(root);
}

//后序递归
template<class Elem>
void BinTree<Elem>::pos(BinNode<Elem>* root){
	
	if(root == NULL)
		return;
	pos(root->left);
	pos(root->right);
	cout << root->data << " ";

}

//后序迭代
template<class Elem>
void BinTree<Elem>::ipos(BinNode<Elem>* root){

	stack<BinNode<Elem>*> st;
	BinNode<Elem>* pre = NULL;
	
	while(root)
	{
		st.push(root);
		root = root->left;
		while(root == NULL && !st.empty())
		{
			root = st.top();
			if(pre == root->right || !root->right)
			{
				st.pop();
				cout << root->data << " ";
			}
			pre = root;
			root = root->right;
		}
	}

}

//后序遍历
template<class Elem>
void BinTree<Elem>::posOrderTraversal(){
	
	cout << "1.递归方法:";
	pos(root);
	cout <<endl;
	cout << "2.迭代方法:";
	ipos(root);
	
}

//层序遍历(用队列实现)
template<class Elem>
void BinTree<Elem>::lay(BinNode<Elem>* root){

	queue<BinNode<Elem>*> q;
	q.push(root);
	
	while(root)
	{
		cout << root->data << " ";
		if(root->left)
			q.push(root->left);
		if(root->right)
			q.push(root->right);
		q.pop();
		root = q.front();
	}
	
}

template<class Elem>
void BinTree<Elem>::layOrderTraversal(){

	lay(root);
}

template<class Elem>
BinNode<Elem>* BinTree<Elem>::find(Elem p,BinNode<Elem>* root){

	BinNode<Elem>* temp = NULL;

	if(root == NULL)
		temp = NULL;
	if(root->data == p)
		return root;
	temp = find(p,root->left);
	return temp ? temp : find(p,root->right);

}

template<class Elem>
bool BinTree<Elem>::insert(Elem p,int LR,int data){

	bool flag = false;
	
	BinNode<Elem>* temp = find(p,root);
	BinNode<Elem>* node = new BinNode<Elem>(data);
	if(temp)
	{
		if(LR == 0)
		{
			if(temp->left == NULL)
			{
				temp->left = node;
				flag = true;
			}
				
		}
		if(LR == 1)
		{
			if(temp->right == NULL)
			{
				temp->right = node;
				flag = true;
			}
		}
	}
	
	return flag;
}


int main(int argc,const char *argv[]){

	BinTree<int> r(1);
	/*
	BinNode<int>* node1 = new BinNode<int>(2);
	BinNode<int>* node2 = new BinNode<int>(3);
	BinNode<int>* node3 = new BinNode<int>(4);
	BinNode<int>* node4 = new BinNode<int>(5);
	
	node1->left = node3;
	node2->right = node4;
	
	r.root->left = node1;
	r.root->right = node2;
	*/
	r.insert(1,0,2);
	r.insert(1,0,3);
	r.insert(1,1,3);
	r.insert(2,0,4);
	r.insert(2,1,5);
	r.insert(4,0,6);

	cout << "前序遍历"<<endl;
	r.preOrderTraversal();
	cout << endl;
	cout << "中序遍历"<<endl;
	r.midOrderTraversal();
	cout << endl;
	cout << "后序遍历"<<endl;
	r.posOrderTraversal();
	cout << endl << endl;
	cout << "层序遍历:";
	r.layOrderTraversal();
	
	
	
	return 0;
}


C实现

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

#define Elem int

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

void init(BinNode** root,Elem data){
	
	*root = (BinNode*)malloc(sizeof(BinNode));
	(*root)->data = data;
	(*root)->left = NULL;
	(*root)->right = NULL;
}

BinNode* find(BinNode* root,Elem p){
	
	BinNode* temp = NULL;
	if(root == NULL)
		temp = NULL;
	else
	{
		if(root->data == p)
			temp = root;
		else
		{
			temp = find(root->left,p);
			return temp ? temp:find(root->right,p);
		}
	}
	
	return temp;
	
}

int insert(BinNode* root,Elem p,int LR,Elem data){
	
	int flag = -1;
	
	BinNode* temp = find(root,p);
	BinNode* node = (BinNode*)malloc(sizeof(BinNode));
	node->data = data;
	node->left = NULL;
	node->right = NULL;
	
	if(temp == NULL)
		flag = -1;
	else
	{
		if(LR == 0)
		{
			if(temp->left == NULL)
			{
				temp->left = node;
				flag = 0;
			}
		}
		else
		{
			if(temp->right == NULL)
			{
				temp->right = node;
				flag = 0;
			}
		}
	}
	
	return flag;
	
}

//前序遍历:中、左、右
void preOrderTraversal(BinNode* root){
	
	if(root == NULL)
		return;
	printf("%d",root->data);
	preOrderTraversal(root->left);
	preOrderTraversal(root->right);
	
}

//中序遍历:左、中、右
void midOrderTraversal(BinNode* root){
	
	if(root == NULL)
		return;
	midOrderTraversal(root->left);
	printf("%d",root->data);
	midOrderTraversal(root->right);
}

//后序遍历:左、右、中
void posOrderTraversal(BinNode* root){
	
	if(root == NULL)
		return;
	posOrderTraversal(root->left);
	posOrderTraversal(root->right);
	printf("%d",root->data);
}

int main()
{
   /*  Write C code in this online editor and run it. */
	BinNode* root;
	init(&root,1);
	insert(root,1,0,2);
	insert(root,1,1,3);
	insert(root,2,0,4);
	preOrderTraversal(root);
	printf("\n");
	midOrderTraversal(root);
	printf("\n");
	posOrderTraversal(root);
   
   return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值