实验3 二叉树的实现

问题描述实验要求

基于教材内容,实现二叉树。

基本要求

需要基于左子结点/右兄弟结点表示法或二叉链表来实现二叉树ADT

需要实现二叉树的各个基本操作。

一、简要分析:

实现二叉树的方式比较多,因为二叉树的种类就蛮多的,本人是基于BST的规则来实现的,二叉树的基本操作有:查找和插入。删除比较复杂,删除的话需要调整二叉树,使得它平衡,本人这里没有实现删除这一操作。查找分为:前序遍历、中序遍历、后序遍历、层次遍历。

二、具体实现:

如何构造一棵二叉树呢?

建树函数的具体实现如下:
void Btree::create_Btree(int x)
{
    tree *newnode=new tree;
    newnode->data=x;
    newnode->right=newnode->left=NULL;
    if(root==NULL)
        root=newnode;
    else
    {
        tree *back;//指向下一个子节点的父节点位置
        tree *current=root;//前一个节点 作为当前位置
        while(current!=NULL)
        {
            back=current;//先记录父节点的位置
            if(current->data<x)//如果父节点的数据 小于待插入数据元素
                current=current->left;//curr 往左边走,反之往右边走
            else
                current=current->right;
        }

            if(back->data<x)//比较与父节点数据元素与待插入数据元素的大小
                back->left=newnode;//把元素大的插在左边,反之插在右边
            else
                back->right=newnode;
    }
}

不懂这个规则可以先去了解一下BST树。

下面是四种遍历的实现:

扫描二维码关注公众号,回复: 2644477 查看本文章

前序遍历就是:父-->左子树-->右子树 简记为:根左右

中序遍历就是:左根右

后序遍历:左右根

层序遍历我就不多说啦,按层遍历。

void BTree::PreorderTravel_tree(tree* temp)//前序
{
	if(temp!=NULL)
	{
		cout<<temp->data<<" ";
		PreorderTravel_tree(temp->left_node);
		this->PreorderTravel_tree(temp->right_node);
	}
	else return ;
}

void BTree::InorderTravel_tree(tree* temp)//中序
{
	if(temp!=NULL)
	{
		this->InorderTravel_tree(temp->left_node);
		cout<<temp->data<<" ";
		this->InorderTravel_tree(temp->right_node);
	}
	else return ;
}

void BTree::PosorderTravel_tree(tree* temp)//后序
{
	if(temp!=NULL)
	{
		this->PosorderTravel_tree(temp->left_node);
		this->PosorderTravel_tree(temp->right_node);
		cout<<temp->data<<" ";
	}
	else return ;
}

int BTree::CenciTravel_tree(tree* temp,int level)//层次
{
	if(temp==NULL|| level<0)
	{
		return 0;
	}
	else if(level == 0)
	{
		cout<<temp->data<<" ";
		return 1;
	}
	else
	{	
		return CenciTravel_tree(temp->left_node,level-1)+CenciTravel_tree(temp->right_node,level-1);
	}
}

插入一个节点:

实现思路:先判断新节点的值与根节点的大小关系,决定新节点放在左子树还是右子树。依此比较下去,直到找到可以放的位置,嗅到了递归的味道,emmm其实就是用递归。我们建树的时候就是这样干的,所以插入新节点只需调用前面的creat函数即可。

下面附完整代码:

//main.cpp
#include<iostream>
#include<cstring>
#include"BTree.h" 
using namespace std; 

int main()
{
	BTree btree;//定义一个对象 
	int ch[]={100,100,4,3,15,35,6,1};
	int len=sizeof(ch)/sizeof(ch[0]);
	cout<<"待插入节点排序:"<<endl;
	for(int i=0;i<len;i++)
	{	
		cout<<ch[i]<<" "; 
		btree.Create_BTree(ch[i]); 
	}
	cout<<endl;
	cout<<"前序遍历:"<<endl;
	btree.Display_Pre();
	cout<<"中序遍历:"<<endl;
	btree.Display_In(); 
	cout<<"后序遍历:"<<endl;
	btree.Display_Pos();
	cout<<"节点个数:"<<endl;
	cout<<btree.count_node(btree.root)<<endl;
	cout<<"叶子个数:"<<endl;
	cout<<btree.count_leaf(btree.root)<<endl; 
	cout<<"层次遍历:"<<endl;
	int h = btree.Gethight(btree.root);
	btree.CenciTravel_tree(btree.root,h);
	btree.LevelOrder(btree.root);
	return 0;
} 

//BTree.h
#ifndef _BTREE_INCLUDE_
#define _BTREE_INCLUDE_
#include<iostream>
using namespace std;
class tree{
	public:
	int data;
	tree* left_node;
	tree* right_node;
};

class BTree{
	private:
		 static int node_count;
		 static int leaf_count;
	public:
		tree* root;
		BTree(){ root = NULL;}
		void Create_BTree(int);
		void PreorderTravel_tree(tree*);
		void InorderTravel_tree(tree*);
		void PosorderTravel_tree(tree*);
		int CenciTravel_tree(tree*,int);
		int count_node(tree*);
		int count_leaf(tree*);
		int count_node_DP(tree*,int);
		void Display_Pre(){ this->PreorderTravel_tree(root);cout<<endl;}
		void Display_In(){this->InorderTravel_tree(root);cout<<endl;}
		void Display_Pos(){this->PosorderTravel_tree(root);cout<<endl;}
		int Gethight(tree*);
		void LevelOrder(tree*);
};
#endif
//BTree.cpp
#include"BTree.h"
int BTree::node_count=0;
int BTree::leaf_count=0;
void BTree::Create_BTree(int ch)
{
	tree* newnode = new tree;
	newnode->data = ch;
	newnode->left_node=newnode->right_node = NULL;
	if(root==NULL)
	{
		root = newnode;
	}
	else
	{
		tree* current = root;
		tree* back;
		while(current!=NULL)
		{
			back = current;
			if(ch > current->data)
			{
				current=current->left_node;
			}
			else
			{
				current=current->right_node;
			}
		}
			if(ch > back->data)
			{
				back->left_node = newnode;
			}
			else
			{
				back->right_node = newnode;
			}
		
	}
}

void BTree::PreorderTravel_tree(tree* temp)
{
	if(temp!=NULL)
	{
		cout<<temp->data<<" ";
		PreorderTravel_tree(temp->left_node);
		this->PreorderTravel_tree(temp->right_node);
	}
	else return ;
}

void BTree::InorderTravel_tree(tree* temp)
{
	if(temp!=NULL)
	{
		this->InorderTravel_tree(temp->left_node);
		cout<<temp->data<<" ";
		this->InorderTravel_tree(temp->right_node);
	}
	else return ;
}

void BTree::PosorderTravel_tree(tree* temp)
{
	if(temp!=NULL)
	{
		this->PosorderTravel_tree(temp->left_node);
		this->PosorderTravel_tree(temp->right_node);
		cout<<temp->data<<" ";
	}
	else return ;
}

int BTree::CenciTravel_tree(tree* temp,int level)
{
	if(temp==NULL|| level<0)
	{
		return 0;
	}
	else if(level == 0)
	{
		cout<<temp->data<<" ";
		return 1;
	}
	else
	{	
		return CenciTravel_tree(temp->left_node,level-1)+CenciTravel_tree(temp->right_node,level-1);
	}
}
int BTree::count_node(tree* temp)
{ 
	if(temp==NULL) return 0;
	else
	return this->count_node(temp->left_node)+this->count_node(temp->right_node)+1;
}

int BTree::count_leaf(tree* temp)
{
	if(temp==NULL) return 0;
	else
	{
		if(temp->left_node==NULL&&temp->right_node==NULL) return leaf_count+=1;
		else
		{
			this->count_leaf(temp->left_node);
			this->count_leaf(temp->right_node);
		}
		return leaf_count;
	}
}

int BTree::Gethight(tree* temp)
{
	if(temp==NULL)  return 0;
	int lefthight = Gethight(temp->left_node);
	int righthight = Gethight(temp->right_node);
	if(lefthight > righthight)
	{
		return lefthight+1;
	}
	return righthight+1;
}

void BTree::LevelOrder(tree* temp)
{
	for(int i=0;i<this->Gethight(root);i++)
	{	
		cout<<"µÚ"<<i+1<<"²ã£º"; 
	if(!this->CenciTravel_tree(root,i))
		break;
		cout<<endl;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42294984/article/details/81511057