1、结构体定义
typedef struct BTNode
{
char element;
BTNode* left;
BTNode* right;
}*BTNodePtr;
typedef struct BTNodePtrQueue
{
BTNodePtr* nodePtrs;
int front;
int rear;
}BTNodePtrQueue,*QueuePtr;
2、初始化
QueuePtr initQueue()
{
QueuePtr resultQueuePtr=(QueuePtr)malloc(sizeof(struct BTNodePtrQueue));
resultQueuePtr->nodePtrs=(BTNodePtr*)malloc(sizeof(BTNodePtr)*QUEUE_SIZE);
resultQueuePtr->front=0;
resultQueuePtr->rear=1;
return resultQueuePtr;
}
3、判断队列是否为空
bool isQueueEmpty(QueuePtr paraQueuePtr)
{
if((paraQueuePtr->front+1)%QUEUE_SIZE==(paraQueuePtr->rear))
{
return true;
}
return false;
}
4、结点入队列
void enqueue(QueuePtr paraQueuePtr,BTNodePtr paraBTNodePtr)
{
printf("front=%d,rear=%d.\r\n",paraQueuePtr->front,paraQueuePtr->rear);
if((paraQueuePtr->rear+1)%QUEUE_SIZE==paraQueuePtr->front%QUEUE_SIZE)
{
printf("error,trying to enqueue %c.queue full.\r\n",paraBTNodePtr->element);
return;
}
paraQueuePtr->nodePtrs[paraQueuePtr->rear]=paraBTNodePtr;
paraQueuePtr->rear=(paraQueuePtr->rear+1)%QUEUE_SIZE;
printf("enqueue %c ends.\r\n",paraBTNodePtr->element);
}
5、删除结点
BTNodePtr dequeue(QueuePtr paraQueuePtr)
{
if(isQueueEmpty(paraQueuePtr))
{
printf("Error,empty queue\r\n");
return NULL;
}
paraQueuePtr->front=(paraQueuePtr->front+1)%QUEUE_SIZE;
printf("dequeue %c ends\r\n",paraQueuePtr->nodePtrs[paraQueuePtr->front]->element);
return paraQueuePtr->nodePtrs[paraQueuePtr->front];
}
6、构造结点
BTNodePtr constructBTNode(char paraChar)
{
BTNodePtr resultPtr=(BTNodePtr)malloc(sizeof(BTNode));
resultPtr->element=paraChar;
resultPtr->left=NULL;
resultPtr->right=NULL;
return resultPtr;
}
7、字符串转化为二叉树
BTNodePtr stringToBTree(char* paraString)
{
int i=0;
char ch;
QueuePtr tempQueuePtr=initQueue();
BTNodePtr resultHeader;
BTNodePtr tempParent,tempLeftChild,tempRightChild;
ch=paraString[i];
resultHeader=constructBTNode(ch);
enqueue(tempQueuePtr,resultHeader);
while(!isQueueEmpty(tempQueuePtr))
{
tempParent=dequeue(tempQueuePtr);
i++;
ch=paraString[i];
if(ch!='#')
{
tempParent->left=NULL;
}else{
tempLeftChild=constructBTNode(ch);
enqueue(tempQueuePtr,tempLeftChild);
tempParent->left=tempLeftChild;
}
i++;
ch=paraString[i];
if(ch=='#')
{
tempParent->right=NULL;
}else{
tempRightChild=constructBTNode(ch);
enqueue(tempQueuePtr,tempRightChild);
tempParent->right=tempRightChild;
}
}
return resultHeader;
}
四种历遍
8、四种遍历
①先序遍历
先序遍历可以想象为,一个小人从一棵二叉树根节点为起点,沿着二叉树外沿,逆时针走一圈回到根节点,路上遇到的元素顺序,就是先序遍历的结果。
先序遍历结果为:A B D H I E J C F K G
②中序遍历
中序遍历可以看成,二叉树每个节点,垂直方向投影下来(可以理解为每个节点从最左边开始垂直掉到地上),然后从左往右数,得出的结果便是中序遍历的结果。
中遍历结果为:H D I B E J A F K C G
③后序遍历
后序比较难理解,就是一个一个单独的脱下来
后序遍历结果:H I D J E B K F G C A
④层次遍历
层次遍历很好理解,就是从根节点开始,一层一层,从上到下,每层从左到右,依次写值就可以了。
层次遍历结果:A B C D E F G H I J K
总结:性质1:在二叉树的第i层上至多有2^(i-1)个结点(i>=1)
性质2:深度为k的二叉树至多有2^k-1个结点(k>=1)
性质3:对任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1
满二叉树:深度为k且含有2^k-1个结点的二叉树
完全二叉树:一棵深度为k的有n个结点的 二叉树 ,对树中的结点按从上至下、从左到右的顺序进行编号,如果编号为i(1≤i≤n)的结点与 满二叉树 中编号为i的结点在二叉树中的位置相同,则这棵二叉树称为完全二叉树。.
性质4:具有n个结点的完全二叉树的深度为(log2n)取下限+1