數據結構與算法學習筆記——二叉樹的初步理解

二叉樹的概念


二叉樹是一棵每個節點都不能有多於兩個兒子的樹
有N個結點的完全二叉樹的深度:

公式:K =「log2n」+1
證明:可用數學歸納法。
當n=1=2^1-1時顯然。
假設當n<=2^k-1時具有n個結點的完全二叉樹的深度爲「log2n」+1,則
當n=2^k(以及2^k+1,…,2^(k+1)-1)時,由歸納假設知前2^k-1個結點構成深度爲「log2n」+1的樹,再由完全二叉樹的定義知剩餘的1(或2,…,2^k)個結點均填在第「log2n」+2層上(作爲“葉子”),故深度剛好增加了1。
故n<=2^(k+1)-1時命題成立。證畢。
(首先最好能先從直觀上理解:完全二叉樹中:
第1層有1個結點;
第2層有2個結點;
第3層有4個結點;
……
第k層有2^(k-1)個結點;(前k層共有(2^k)-1個結點,故前面深度剛好是「log2(2^k-1)」+1=k-1+1=k)
第k+1層是剩餘的結點。

二叉樹的平均深度爲 O((n) ),二叉查找數的深度平均值是O(logN)

二叉樹的實現

因爲一個二叉樹結點最多有兩個兒子,所以可以直接鏈接到它們。樹節點的聲明在結構上類似於雙向鏈表的聲明。在聲明中,一個結點就是由element的信息加上兩個到其他結點的引用(leftright )組成的結構。

struct BinaryNode
{
  Object  element;    //data in the node
  BinaryNode *left;   //Left child
  BinaryNode *right;  //Right child
}

二叉樹的創建

#include<iostream>
using namespace std;
typedef struct node
    {
        struct node *leftChild;
        struct node *rightChild;
        char data;
    }BiTreeNode ,*BiTree;
//————————建立二叉樹——————————
void createBitree(BiTree &T)
    {
        char c;
        cin>>c;
        if('#'==c)
            T==NULL;
        else
        {
            T=new BiTreeNode;
            T->data=c;
            createBitree(T->leftChild);
            createBitree(T->rightChild);
        }
    }
int _tmain(int argc, _TCHAR* argv[])
{
    BiTree T;
    int numNode;
    createBitree(T);
    cout<<"二叉樹建立完成"<<endl;
    system("pause");
    return 0;
}

二叉樹常見問題

題目參照:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888
1)遍歷:前序,中序,後序
2)結點個數:
遞歸解法:
(1)如果二叉樹爲空,節點個數爲0
(2)如果二叉樹不爲空,二叉樹節點個數 = 左子樹節點個數 + 右子樹節點個數 + 1
3) 求二叉樹的深度
遞歸解法:
(1)如果二叉樹爲空,二叉樹的深度爲0
(2)如果二叉樹不爲空,二叉樹的深度 = max(左子樹深度, 右子樹深度) + 1
4)分層遍歷二叉樹(按層次從上往下,從左往右)
相當於廣度優先搜索,使用隊列實現。隊列初始化,將根節點壓入隊列。當隊列不爲空,進行如下操作:彈出一個節點,訪問,若左子節點或右子節點不爲空,將其壓入隊列。

常見問題的程序實現

// three_order_map.cpp : 定義控制檯應用程序的入口點。
//
#include"stdafx.h"
#include<iostream> 
#include<queue>

#define N 7  
using namespace std;  

typedef struct node  
{  
    struct node *leftChild;  
    struct node *rightChild;  
    int data;  
}BiTreeNode, *BiTree;  

BiTreeNode *createNode(int i)  
{  
    BiTreeNode * q = new BiTreeNode;  
    q->leftChild = NULL;  
    q->rightChild = NULL;  
    q->data = i;  //1,2,3,4,5,6也可以自己輸入

    return q;  
}  

BiTree createBiTree()  
{  
    BiTreeNode *p[N] = {NULL};  
    int i;  
    for(i = 0; i < N; i++)  
        {
            p[i] = createNode(i + 1);
            cout<<p[i]->data<<endl;
        }

    for(i = 0; i < N/2; i++)  
    {  
        p[i]->leftChild = p[i * 2 + 1];  
        p[i]->rightChild = p[i * 2 + 2];  
    }  

    return p[0];  
}  

int visit(BiTree T)  
{  
    return T->data;  
}  

// 先序遍歷  
void preOrderTraverse(BiTree T)  
{  
    if(T)  
    {  
        cout << visit(T) << " ";  
        preOrderTraverse(T->leftChild);  
        preOrderTraverse(T->rightChild);  
    }  
}  

// 中序遍歷  
void inOrderTraverse(BiTree T)  
{  
    if(T)  
    {  
        inOrderTraverse(T->leftChild);  
        cout << visit(T) << " ";  
        inOrderTraverse(T->rightChild);  
    }  
}  

// 後序遍歷  
void postOrderTraverse(BiTree T)  
{  
    if(T)  
    {  
        postOrderTraverse(T->leftChild);  
        postOrderTraverse(T->rightChild);  
        cout << visit(T) << " ";  
    }  
}  

//求二叉樹中的結點個數
int GetNodeNum(BiTreeNode * pRoot)  
{  
    if(pRoot == NULL) // 遞歸出口  
        return 0;  
    return GetNodeNum(pRoot->leftChild) + GetNodeNum(pRoot->rightChild) + 1;  
}  

//求二叉樹的深度
int GetDepth(BiTreeNode * pRoot)  
{  
    if(pRoot == NULL) // 遞歸出口  
        return 0;  
    int depthLeft = GetDepth(pRoot->leftChild);  
    int depthRight = GetDepth(pRoot->rightChild);  
    return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);   
}  
//分層遍歷二叉樹
void LevelTraverse(BiTreeNode * pRoot)  
{  
    if(pRoot == NULL)  
        return;  
    queue<BiTreeNode *> q;  
    q.push(pRoot);  
    while(!q.empty())  
    {  
        BiTreeNode * pNode = q.front();  
        q.pop();  
        cout<<visit(pNode); // 訪問節點  
        if(pNode->leftChild != NULL)  
            q.push(pNode->leftChild);  
        if(pNode->rightChild != NULL)  
            q.push(pNode->rightChild);  
    }  
    return;  
}  
int main()  
{  
    int num;
    BiTree T = createBiTree();  //根節點

    cout << "先序遍歷:" << endl;  
    preOrderTraverse(T);  
    cout << endl << endl;  

    cout << "中序遍歷:" << endl;  
    inOrderTraverse(T);  
    cout << endl << endl;  

    cout << "後序遍歷:" << endl;  
    postOrderTraverse(T);  
    cout << endl << endl;  

    num=GetNodeNum(T);
    cout<<"結點個數爲 "<<num<<endl;

    num=GetDepth(T);
    cout<<"樹的深度爲 "<<num<<endl;

    cout<<"層次遍歷的結果爲:";
    LevelTraverse(T);
    cout<<endl;

    system("pause");
    return 0;  
}  

這裏寫圖片描述

由於博主的學識有限,難免會出現錯誤,歡迎大家在評論區批評,指正,交流,也歡迎大家對博文的內容上的繼續補充

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章