zoukankan      html  css  js  c++  java
  • 数据结构——二叉树

    一、二叉树的定义

    二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

    二、二叉树的特点

    1、每个结点最多有两颗子树。

    2、左子树和右子树是有序的。

    3、即使树中只有一课子树也要区分左右子树。

    二叉树具有五种基本形态:

    1、空二叉树。

    2、只有一个根结点。

    3、根结点只有左树。

    4、根结点只有右树。

    5、根结点既有左子树又有右子树。

    三、特殊二叉树

    1、斜树

    所有的结点都只有左子树的二叉树叫做左斜树,所有结点都是只有右子树的二叉树叫右斜树。

    2、满二叉树

    在一颗二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样树称为满二叉树。

    3、完全二叉树

    对一颗具有n个结点的二叉树按层次编号,如果编号i (1<=i <=n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵树称为完全二叉树。

    四、二叉树的性质

    1、在二叉树的第i层上至多有2^(i-1)个结点(i>=1)

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

    3、对任何一颗二叉树T,如果其终端结点数为n0,深度为2的结点树为n2,则n0 = n2 + 1;

    4、具有n个结点的完全二叉树的深度为log2^n+1

    5、如果对一颗有n个结点的完全二叉树(其深度为log2^n+1)的结点按层序编号,对任一结点有:

    (1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲是结点[i/2].

    (2)如果2i >n,则结点i无左孩子;否则其左孩子是结点2i

    (3)如果2i+1>n,则结点i无右孩子,否则其右孩子是结点2i+1.

    五、二叉树的实现

    #include <iostream>
    using namespace std;
    typedef char T;
    
    class bst{
    	//定义二叉查找树
    	struct Node{
    		T data;
    		Node* L;
    		Node* R;
    		Node(const T& d):data(d), L(), R(){}
    		Node(const T& d, Node *l, Node *r):data(d), L(l), R(r){}
    	};
    	typedef Node* tree;
    	Node * rp;
    	int n;
    public:
    	bst():rp(), n(){}
    	//清空
    	void clear(){
    		clear(rp);
    		n = 0;
    	}
    	//析构函数
    	~bst(){
    		clear();
    	}
    	//插入
    	void insert(const T& d){
    		insert(rp, new Node(d));
    		++n;
    	}
    	//查找
    	tree& find(const T& d){
    		return find(rp, d);
    	}
    	//遍历
    	void travel()const{
    		travel(rp);
    		cout << endl;
    	}
    	//判断树是否为空
    	bool empty()const{
    		return rp==NULL;
    	}
    	//返回树的结点数
    	int size()const{
    		return n;
    	}
    	//移除某个结点
    	bool remove(const T& d){
    		tree& t = find(d);
    		if(t == NULL) return false;
    		Node* p = t;
    		if(t->L != NULL){
    			insert(t->R, t->L);
    		}
    		t = t->R;
    		delete p;
    		return true;
    	}
    
    	//获取根结点数据
    	const T& root()const{
    		if(rp == NULL) return NULL;
    		else return rp->data;
    	}
    
    	//插入结点
    	void insert(tree& t, Node *p){
    		if(t == NULL){ //如果根结点为NULL,空树
    			t = p;	
    		}else if(p->data < t->data){
    			insert(t->L, p); //插入左子树
    		}else{
    			insert(t->R, p); //插入右子树
    		}
    	}
    
    	//查找数据
    	//返回以d为根的子树的根指针
    	tree& find(tree& t, const T& d){
    		if(t == NULL){
    			return t; //没找到 
    		}else if(d == t->data){
    			return t; //找到了
    		}else if(d < t->data){
    			return find(t->L, d);
    		}else{
    			return find(t->R, d); 
    		}
    	}
    
    	//遍历二叉树
    	void travel(tree t)const{
    		if(t != NULL){
    			//中序遍历
    			travel(t->L);
    			cout << t->data << ' ';
    			travel(t->R);
    		}
    	}
    
    	//清空树
    	void clear(tree& t){
    		if(t != NULL){
    			//后序遍历
    			clear(t->L);
    			clear(t->R);
    			delete t;
    			t = NULL;
    		}
    	}
    
    	//获取树的层数
    	int high(tree& t){
    		if(t == NULL) return 0;	
    		int lh = high(t->L);
    		int rh = high(t->R);
    		//最高子树高度再加根结点高度1
    		return 1 + (lh > rh ? lh : rh);
    	}
    
    
    
    }; 
    
    int main(){
    	bst b;
    	b.insert('k');
    	b.insert('s');
    	b.insert('f');
    	b.insert('t');
    	b.insert('a');
    	b.insert('m');
    	b.insert('x');
    	b.insert('e');
    	b.insert('w');
    	b.insert('b');
    	b.insert('u');
    	b.insert('j');
    	b.travel();
    	cout << "**********remove k,m,u,j******" << endl;
    	b.remove('k');
    	b.remove('m');
    	b.remove('u');
    	b.remove('j');
    	b.travel();
    	cout << "**********remove root*********" << endl;
    	while(!b.empty()) b.remove(b.root);
    	cout << "size:" << b.size() << endl;
    	b.travel();
    
    	return 0;
    }
    

  • 相关阅读:
    NTFS文件系统的主要优点体现在以下三个方面
    子网划分,主机号,网络号计算
    hdu1008
    hdu1006
    hdu1004
    Git 版本回退
    Git 提交修改内容和查看被修改的内容
    Git 怎么创建本地库,向本地库提交文件
    mybatis中#{}和${}的区别
    请求头和响应头
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6468629.html
Copyright © 2011-2022 走看看