数据结构_树_二叉树性质/二叉树存储结构/二叉树相应操作(建立、遍历 )

原创 2017年01月03日 21:39:07

二叉树性质:性质1:二叉树第i层上至多有2^(i-1)个结点       (i >= 1)

                      性质2:深度为k的二叉树至多有2^k-1个结点(k >= 1)

                      性质3:对任意二叉树,叶子结点个数count = n(度为2的结点个数)  + 1;

                      性质4:具有n个结点的二叉树,深度为不大于(logn/log2)的最大整数 + 1

                      性质5:有n个结点的完全二叉树,从上往下从左往右编号为i,则不大于i/2的最大整数位该结点的双亲

                                   点,2i为该结点的左孩子结点,2i+1位该结点的右孩子节点。

二叉树存储结构:顺序存储结构,二叉链表

顺序存储结构:

对于顺序存储结构存储树这种一对多的数据结构来说比较困难,因为没有明确的规律可言,。但是对于完全二叉树,我们可以通过简单的一维数组的下标进行相应的计算([i/2]、2i、2i+1)得出当前结点的双亲节点、左孩子节点和右孩子节点等。但是,此存储结构有一缺点,如下:


就会造成大量的存储空间浪费,所以顺序存储结构一般只适应于完全二叉树。

二叉链表:

由于二叉树每一个节点最多有两个孩子,所以一个数据域data,两个指针域lchild,rchild的设计比较自然。

#define char ElemType
typedef struct BtNode
{
      ElemType data;    //当前结点的数据域
      BitNode *lchild;   //指向左孩子的指针
      BitNode *rchild;   //指向右孩子的指针
}BtNode,*BTree;

二叉树的相应操作:

    BtTree();
    ~BtTree();
    void setTree(BtNode *r){tree = r; }
    BtNode *createBtTree();
    void inOrder(){ inOrder(tree); cout<<endl;}                //中序遍历(递归) 
    void NotReInOrder();                                       //中序遍历(非递归) 
    void preOrder(){preOrder(tree);cout<<endl;}                //前序遍历(递归)   
    void NotRePreOrder();                                      //前序遍历(非递归)   
    void postOrder(){postOrder(tree);cout<<endl; }             //后序遍历(递归) 
    void NotRePostOrder();                                     //后序遍历(非递归)   
    int BtTreeSize(){return BtTreeSize(tree); cout<<endl;}     //求结点个数  
    int BtTreeLeaves(){return BtTreeLeaves(tree); cout<<endl;} //求叶子节点个数  
    int BtTreeHeight(){return BtTreeHeight(tree);cout<<endl; } //求树高  

//用于子类继承
protected: 
    void inOrder(BtNode *);                                   //中序遍历   
    void preOrder(BtNode *);                                  //前序遍历  
    void postOrder(BtNode *);                                 //后序遍历 
    int BtTreeSize(BtNode *);                                 //结点个数 
    int BtTreeLeaves(BtNode *);                               //叶子结点   
    int BtTreeHeight(BtNode *);                               //树高 

传入二级指针是为了在函数体内部改变指针的指向。具体的代码实现如下:

二叉树操作实现:[C++]

BtTree.h:

#pragma once
#define END '#'

template
class BtTree
{
public:
	typedef struct BtNode;
	BtTree();
	~BtTree();
	void setTree(BtNode *r){tree = r; }
	BtNode *createBtTree();
	BtNode *createBtTree(T *&str);                                              //带参数的建树函数
	void inOrder(){ inOrder(tree); cout<


BtTree.cpp:

#include 
#include 
#include "BtTree.h"
using namespace std;

//-----------------------------------------------------------------------------------------------------------------------------------------//
//构造函数
template
BtTree::BtTree()
{
	cout<<"BtTree()"<
BtTree::~BtTree(){cout<<"~BtTree()"<
typename BtTree::BtNode * BtTree::createBtTree()
{
	BtNode *current = nullptr;
	T ch;
	cin>>ch;
	if (ch == END)
	{
		return nullptr;
	}
	else
	{
		current = new BtNode;
		current->data = ch;
		current->lchild = createBtTree();
		current->rchild = createBtTree();
	}
	return current;
}
//针对int型数据的特例化模板
BtTree::BtNode * BtTree::createBtTree()
{
	BtNode *current = nullptr;
	int ch;
	cin>>ch;
	if (ch == -1)
	{
		return nullptr;
	}
	else
	{
		current = new BtNode;
		current->data = ch;
		current->lchild = createBtTree();
		current->rchild = createBtTree();
	}
	return current;
}

template
typename BtTree::BtNode *BtTree::createBtTree(T *&str)
{
	BtNode *s = nullptr;
	if (str == nullptr)
	{
		return nullptr;
	}
	while (*str != END)
	{
		s = new BtNode;
		s->data = *str;
		s->lchild = createBtTree(++str);
		s->rchild = createBtTree(++str);
	}
	return s;
}
//-----------------------------------------------------------------------------------------------------------------------------------------//
//中序遍历(递归)
template
void BtTree::inOrder(BtNode * t)
{
	if (t == nullptr)
	{
		return ;
	}
	inOrder(t->lchild);
	cout<data<rchild);
}
//-----------------------------------------------------------------------------------------------------------------------------------------//
//中序遍历(非递归)
template
void BtTree::NotReInOrder()
{
	stack s;
	BtNode * r = tree;
	
	while (!s.empty() || r != nullptr)
	{
		while (r != nullptr)
		{
			s.push(r);
			r = r->lchild;
		}
		if (!s.empty())
		{
			r = s.top();
			s.pop();
			cout<data<rchild;
		}
	}
	cout<
void BtTree::preOrder(BtNode *t)
{
	if (t == nullptr)
	{
		return ;
	}
	cout<data<lchild);
	preOrder(t->rchild);
}
//-----------------------------------------------------------------------------------------------------------------------------------------//
//前序遍历(非递归)
template
void BtTree::NotRePreOrder()
{
	stack s;
	BtNode* r = tree;
	s.push(r);

	while (!s.empty())
	{
		//先访问根结点
		r = s.top();
		s.pop();
		cout<data< 根据栈的特性,应该是右子树先入栈后出栈
		if (r->rchild != nullptr)
		{
			s.push(r->rchild);
		}
		if (r->lchild != nullptr)
		{
			s.push(r->lchild);
		}
	}
	cout<
void BtTree::postOrder(BtNode *t)
{
	if (t == nullptr)
	{
		return ;
	}
	postOrder(t->lchild);
	postOrder(t->rchild);
	cout<data<
class Node
{
private:
	typename BtTree::BtNode *tp;
	bool flag;
	template
	friend class BtTree;
};

template
void BtTree::NotRePostOrder()
{
	stack> s;
	BtNode *r = tree;
	Node node;

	while(!s.empty()||r!=0)  
    {  
        while(r!=0)  
        {  
            node.tp = r;
            node.flag=0;  
            s.push(node);  
            r=r->lchild;  
        }  
  
        if(!s.empty())  
        {  
            node=s.top();  
            s.pop();  
            r=node.tp; //将栈顶的BTreeNode*部分赋给r  
            if(node.flag==1)  
            {  
                cout<data<<" ";  
                r=0; //表示已经访问了该结点  
            }  
            else  
            {  
                node.flag=1;  
                s.push(node);  
                r=r->rchild;  
            }  
        }  
    }
	cout<
int BtTree::BtTreeSize(BtNode * t)
{
	if (t == nullptr)
	{
		return 0;
	}
	return 1+ BtTreeSize(t->lchild)+BtTreeSize(t->rchild);
}
//-----------------------------------------------------------------------------------------------------------------------------------------//
//求叶子节点的个数
template
int BtTree::BtTreeLeaves(BtNode * t)
{
	if (t == nullptr)
	{
		return 0;
	}
	if (t->lchild == nullptr && t->rchild == nullptr)
	{
		return 1;
	}
	else
	{
		return BtTreeLeaves(t->lchild)+BtTreeLeaves(t->rchild);
	}
}
//-----------------------------------------------------------------------------------------------------------------------------------------//
//求树的高度
template
int BtTree::BtTreeHeight(BtNode * t)
{
	if (t == nullptr)
	{
		return 0;
	}
	else
	{
		int lheight = BtTreeHeight(t->lchild);
		int rheight = BtTreeHeight(t->rchild);
		return (lheight > rheight) ? lheight+1 : rheight+1;
	}
}
//-----------------------------------------------------------------------------------------------------------------------------------------//


int main()
{
	BtTree t1;
	//BtTree t1;
	t1.setTree(t1.createBtTree());
	//char *str = "ABC##DE##F##G#H##";
	//t1.setTree(t1.createBtTree(str));
	cout<<"--------------------------------------------------------------------------------------"<








版权声明:本文为博主原创文章,未经博主允许不得转载,希望能在相互交流中共同成长。【大红色:一级标题 绿色:二级标题 二红色:三级标题 黄色:四级标题】

严蔚敏 数据结构 二叉树链式存储结构 遍历等操作

课本 《数据结构(C语言版)(第2版)》 严蔚敏版 树结构的学习。 编译环境:DEV C++ 文件格式为 cpp(c++文件类型),前者的引用函数,在 C 的情况下没完成。 实现: 二叉树的...

数据结构中二叉树的建立与遍历

  • 2014年06月06日 00:13
  • 112KB
  • 下载

数据结构_树_二叉树的建立、遍历、复制与移除_二叉链表存储_C++实现

"head.h" #include using namespace std; class BitNode { public: BitNode(); char ch; BitNod...

数据结构课时设计 二叉树的遍历

  • 2011年05月29日 09:38
  • 360KB
  • 下载

数据结构中二叉树的前序遍历

  • 2011年12月11日 10:09
  • 772B
  • 下载

数据结构与算法简记:按层次顺序遍历和存储二叉树

前面曾经记录过,给出一个按层次顺序排放的存储数据,进而可以构建出一棵二叉树,今天就来简单记录一下,如何按层次顺序遍历二叉树,最后又如何根据二叉树生成层次存储数据,对于满二叉树来讲这十分必要。对与这棵二...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构_树_二叉树性质/二叉树存储结构/二叉树相应操作(建立、遍历 )
举报原因:
原因补充:

(最多只允许输入30个字)