数据结构二叉树算法C/C++

用于看文字描述后容易写出相对应的二叉树算法代码

这篇文章倾向于自用-代码是手撸源码,可以运行

二叉树代码解析


二叉树
一.CTree 建树
1.函数体内输入
2.两种结点
①输入为# 设为NULL
②输入不为# 【abc调换顺序即为三种创建树】
a.申请空间赋值
b.递归左子树
c.递归右子树.

二。.Traversal
T不为NULL 【abc调换顺序即为三种遍历树】
a.访问T
b.递归左子树
c.递归右子树.

三.结点数:
①参数返回: 结点不为空 sum++;
②返回值: T==NULL return0
else 左子树加右子树+1【根结点】

四.叶节点:
①参数返回:
左右孩子都为NULL sum++
左 NULL 递归左
右 NULL 递归右

②返回值:NULL return0   双空return1  else 左+右

五.层数:
NULL 0
return max(左,右)+1 「 例如开始处 max(0,0)+1=1 最底层为第一层 」

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
/*
二叉树
深度N
节点最多【满二叉树】2^n    - 1
第n层  2  ^(n-1)个

*/
typedef struct Tree{
	int data;
	struct Tree *LC;
	struct Tree *RC;
}Tree;

Tree* Init_Tree(){
	Tree *T=NULL;
	return T;
}

void Inorder_Create_Tree(Tree *T){
	int data;
	cin>>data;
	if(data==0)	 T=NULL;
	else{
		T=(Tree*)malloc(sizeof(Tree));
		Inorder_Create_Tree(T->LC);
		T->data=data;
		Inorder_Create_Tree(T->RC);
	}
	
	return;
}

void Preorder_Create_Tree(Tree* &T){
	int data;
	cin>>data;
	if(data==0) T=NULL;
	else{
		T=(Tree*)malloc(sizeof(Tree));
		T->data=data;
		Preorder_Create_Tree(T->LC);
		Preorder_Create_Tree(T->RC);
	}
	
	return ;
}

Tree* Postorder_Create_Tree(Tree *T){
	int data;
	cin>>data;
	if(data==0)	return T;
	T=(Tree*)malloc(sizeof(Tree));
	Postorder_Create_Tree(T->LC);
	Postorder_Create_Tree(T->RC);
	T->data=data;
	return T;
}

void Inorder_Traverse(Tree *T){
	if(T==NULL)	return;
	Inorder_Traverse(T->LC);
	cout<<T->data;
	Inorder_Traverse(T->RC);	
}

void Preorder_Traverse(Tree *T){
	if(T==NULL)	return;
	cout<<T->data;
	Preorder_Traverse(T->LC);
	Preorder_Traverse(T->RC);	
}

void Postorder_Traverse(Tree *T){
	if(T==NULL)	return;
	Postorder_Traverse(T->LC);
	Postorder_Traverse(T->RC);
	cout<<T->data;	
}

int Tree_depth(Tree *T){
	if(T==NULL)	return 0;
	return Tree_depth(T->LC)>Tree_depth(T->RC)?Tree_depth(T->LC)+1:Tree_depth(T->RC)+1;
}

int Tree_leaf(Tree *T){
	if(T==NULL) return 0;
	if(T->LC==NULL && T->RC==NULL) 	return 1;
	return Tree_leaf(T->LC)+Tree_leaf(T->RC);
}

int NodeTree_count(Tree *T){
	if(T==NULL)	return 0;
	return NodeTree_count(T->LC)+NodeTree_count(T->RC)+1;
}

int main(int argc, char *argv[]) {
	Tree *T=Init_Tree();
	//输入的是数字  空格隔开 
	Preorder_Create_Tree(T);
	cout<<"Pre:";
	Preorder_Traverse(T);
	cout<<endl;
	cout<<"In:"; 
	Inorder_Traverse(T);
	cout<<endl;
	cout<<"Post:"; 
	Postorder_Traverse(T);
	cout<<endl;
	cout<<"depth:"<< Tree_depth(T)<<endl;
	cout<<"NodeCount:"<<NodeTree_count(T)<<endl;
	cout<<"Tree_leaf:"<<Tree_leaf(T)<<endl;
	
	return 0;
}

中序线索树

先有一棵树,才能线索化。
一.中序线索化 [原理是把空的指针使用上,左指前驱,右指后继]
1.开始给一个pre=NULL,作用有三:
①启动调用,让第一个结点的前驱指向pre【即NULL】
②利用pre的移动,加上当前结点T, 每次更改一前一后的指针
③pre最终会走向最后一个结点。
然后让pre 的 rtag=1 pre->RC=null

2.启动的调用函数
①先是一个中序框架
②在中间分别写
a.若下一个结点T的左孩子为空,T->LC=pre; ltag=1;

	b.若上一个结点pre!=NULL 且 右孩子为空,pre->RC=T ;rtag=1

	c.pre移动到T

二.中序线索化遍历
for (Tree* f = findfirst(T); f != NULL; f = findnext(f)) {
vis(f);
}

findfirst:
中序第一个是最左边的,所以 while T->LC!=null

findnext:
若右标志是1,直接返回T
findfirst 以他的有孩子为根节点,去寻找第一个结点【此节点即为下雨给结点】

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std; 
/* run this program using the console pauser or add your own getch, system("pause") or input loop */

typedef struct Tree{
	int data;
	int ltag;
	int rtag;
	struct Tree *LC;
	struct Tree *RC;
}Tree;

Tree* Init_Tree(){
	Tree *T=NULL;
	return T;
}

void Inorder_Create_Tree(Tree *T){
	int data;
	cin>>data;
	if(data==0)	 T=NULL;
	else{
		T=(Tree*)malloc(sizeof(Tree));
		Inorder_Create_Tree(T->LC);
		T->data=data;
		Inorder_Create_Tree(T->RC);
	}	
	return;
}

void Preorder_Create_Tree(Tree* &T){
	int data;
	cin>>data;
	if(data==0) T=NULL;
	else{
		T=(Tree*)malloc(sizeof(Tree));
		T->data=data;
		Preorder_Create_Tree(T->LC);
		Preorder_Create_Tree(T->RC);
	}
	
	return ;
}

Tree* Postorder_Create_Tree(Tree *T){
	int data;
	cin>>data;
	if(data==0)	return T;
	T=(Tree*)malloc(sizeof(Tree));
	Postorder_Create_Tree(T->LC);
	Postorder_Create_Tree(T->RC);
	T->data=data;
	return T;
}

void Inorder_Traverse(Tree *T){
	if(T==NULL)	return;
	Inorder_Traverse(T->LC);
	cout<<T->data;
	Inorder_Traverse(T->RC);	
}

void Preorder_Traverse(Tree *T){
	if(T==NULL)	return;
	cout<<T->data;
	Preorder_Traverse(T->LC);
	Preorder_Traverse(T->RC);	
}

void Postorder_Traverse(Tree *T){
	if(T==NULL)	return;
	Postorder_Traverse(T->LC);
	Postorder_Traverse(T->RC);
	cout<<T->data;	
}

int Tree_depth(Tree *T){
	if(T==NULL)	return 0;
	return Tree_depth(T->LC)>Tree_depth(T->RC)?Tree_depth(T->LC)+1:Tree_depth(T->RC)+1;
}

int Tree_leaf(Tree *T){
	if(T==NULL) return 0;
	if(T->LC==NULL && T->RC==NULL) 	return 1;
	return Tree_leaf(T->LC)+Tree_leaf(T->RC);
}

int NodeTree_count(Tree *T){
	if(T==NULL)	return 0;
	return NodeTree_count(T->LC)+NodeTree_count(T->RC)+1;
}

void Th2(Tree* &T, Tree* &pre)
{
	if(T!=NULL){
		Th2(T->LC,pre);
		if(T->LC==NULL){
			T->LC=pre;
			T->ltag=1;
		}
		if(pre!=NULL && pre->RC==NULL){
			pre->RC=T;
			pre->rtag=1;
		}
		pre=T;
		Th2(T->RC,pre);
	}
}

void  Th1(Tree* T){
	Tree *pre=NULL;
	if(T!=NULL){
		Th2(T,pre);
		pre->RC=NULL;
		pre->rtag=1;
	}
}

Tree* findfirst(Tree* T){
	while(T->ltag!=1)
		T=T->LC;
	return T;
}

Tree* findnext(Tree* T){
	if(T!=NULL){
		if(T->rtag!=1){
			
			T=findfirst(T->RC);
			return T;
		}else
				return T->RC; 
	}
}

void Traverse(Tree* T){
	for(Tree *P=findfirst(T);P!=NULL;P=findnext(P)){
		cout<<P->data<<" ";
	}
	cout<<endl;
}

int main(int argc, char *argv[]) {
	Tree *T=Init_Tree();
	//输入的是数字  空格隔开 
	Preorder_Create_Tree(T);
	cout<<"朴素中序遍历:"<<endl; 
	Inorder_Traverse(T);
  	cout<<endl;
	cout<<"中序线索化&&遍历:"<<endl;
	Th1(T);
	Traverse(T);
	return 0;
}

二叉排序树

一.CBST【建立二叉排序树】
给一个数据集 for 调用BST插入

T= =NULL【表示找到位置】 申请空间插入key
T!=NULL 分三种情况、
①.如果key= =T->key 相同无法插入
②keykey 递归左子树
③key>T->key 递归右子树

二.SBST 【二叉排序树搜索】
T!=NULL
== return true
< SBST T->LC
> SBST T->RC

#include <iostream>
#include <cstdlib>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#define Element int 

typedef struct BT{
	Element data;
	struct BT *LC;
	struct BT *RC;	
};

int CBT(BT* &bt,Element key){
	if(bt==NULL){
		bt=(BT*)malloc(sizeof(BT));
		bt->data=key;
		bt->LC=NULL;
		bt->RC=NULL;
		return 1;
	}
	if(key==bt->data)	return 0;
	if(key < bt->data)	CBT(bt->LC,key);
	if(key > bt->data)	CBT(bt->RC,key); 
}

BT* SBT(BT* bt, Element key){
	if(bt==NULL)	return NULL;
	if(bt->data==key)	return bt;
	else if(key < bt->data)	return SBT(bt->LC,key);
	else if(key > bt->data)	return SBT(bt->RC,key);
}

void S(BT* bt){
	if(bt==NULL)	return ;
	cout<<bt->data<<endl;
	S(bt->LC);
	S(bt->RC);
}

int main(int argc, char *argv[]) {
	BT *bt;
	int n;
	cin>>n; 
	bt=NULL;
	int key;
	for(int i=0;i<n;i++){
		cin>>key;
		CBT(bt,key);
	}
	BT *bt1;
	bt1=SBT(bt,5);
	cout<<bt1->data<<endl;
	bt1=SBT(bt,100);
	if(bt1!=NULL)
	cout<<bt1->data<<endl;
	
	return 0;
}

求点赞👍👍👍
原创不易,点赞容易。
您的鼓励就是我的最大动力!!!。

本篇博客到此结束,谢谢大家观看。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值