数据结构与算法学习笔记——二叉树的初步理解

来源:互联网 发布:osx和linux 编辑:程序博客网 时间:2024/05/21 06:54

二叉树的概念


二叉树是一棵每个节点都不能有多于两个儿子的树
有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;  }  

这里写图片描述

由于博主的学识有限,难免会出现错误,欢迎大家在评论区批评,指正,交流,也欢迎大家对博文的内容上的继续补充

0 0
原创粉丝点击