題目:給定一個不含重復元素的整數數組。一個以此數組構建的最大二叉樹定義如下:
- 二叉樹的根是數組中的最大元素。
- 左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。
- 右子樹是通過數組中最大值右邊部分構造出的最大二叉樹。
通過給定的數組構建最大二叉樹,並且輸出這個樹的根節點。
Example 1:
輸入: [3,2,1,6,0,5] 輸入: 返回下面這棵樹的根節點: 6 / \ 3 5 \ / 2 0 \ 1
分析:(1)通過審題可知通過先序創建二叉樹進行創建,即創建根節點,左子樹,右子數。 所以選擇遞歸的方法進行創建。
visit(T);
createleftTree(T->left);
creatterightTree(T->right);
(2)找數組中的最大值,類似於二分查找, 用三個游標low,high,temp分別來跟蹤所要查找的數組中的低位、高位、和最大值的位置。
temp 根節點
[low , temp-1]左子樹
[temp+1, high]右子數
(3)根據題意,輸出時需要將二叉樹按層輸出,即按層遍歷,使用隊列實現,隊列的特性FIFO 。(1)根節點入隊列-》(2)根節點出隊列並輸出-》(3)左子樹入隊列-》(4)右子數入隊列-》(3)
定義二叉樹結點:
typedef struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode;
定義隊列鏈表結點:
typedef struct QNode{
QueuePtr val;
QNode *next;
}QNode,*QueuePtr;
定義隊列:
typedef struct Queue{
QueuePtr front;
QueuePtr rear;
}Queue;
//Q.front 指向隊列鏈表的頭結點;
Q.rear 指向隊列鏈表的尾結點;
入隊列時在Q.rear后加結點,出隊列時在Q.front刪結點
源代碼:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
#include<stdio.h>
#include<stdlib.h>
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};
//定義鏈表隊列
typedef struct QNode {
struct TreeNode *val;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct Queue {
QueuePtr rear ; //隊列尾指針
QueuePtr front; //隊列頭指針
}Queue;
// 找出數組中最大的數
int searchMaxnum(int *nums, int low, int high, int *location) {
int max = -1;
int i;
i = low;
while (i <=high) {
if (max< (*(nums + i)))
{
max = *(nums + i);
*location = i;
}
i++;
}
return max;
}
void createTree(struct TreeNode** p, int *count, int * nums, int low, int *location, int high) {
struct TreeNode* q;
int t,max, t_right, t_left;;
if (low > high)
{
return;
}
if (count == 0)
return;
max = searchMaxnum(nums, low, high, location);
if (max == -1)
return;
*p = q = (struct TreeNode*)malloc(sizeof(struct TreeNode));
(*p)->val = max;
(*p)->left = NULL;
(*p)->right = NULL;
(*count)--;
t_left = (*location) - 1;
t_right = (*location) + 1;
createTree(&((*p)->left), count, nums, low, location, t_left);
createTree(&((*p)->right), count, nums, t_right, location, high);
}
struct TreeNode* constructMaximumBinaryTree(int* nums, int numsSize) {
int maxleft, location,t, t_right, t_left;
int count = numsSize;
int low = 0;
int high = numsSize - 1;
struct TreeNode* p = NULL;
p = (struct TreeNode*)malloc(sizeof(struct TreeNode));
p->val = searchMaxnum(nums, low, high, &location);
count--;
(p)->left = NULL;
(p)->right = NULL;
t_left = location-1;
t_right = location + 1;
//createTree(&p, searchMaxnum(nums, low, high, &location), &count, nums, &low, &location, &high);
createTree(&(p->left), &count, nums, low, &location, t_left);
createTree(&(p->right), &count, nums, t_right, &location, high);
return p;
}
//入隊列
void enqueue(Queue *s, struct TreeNode *t) {
QNode *p;
p = (QNode *)malloc(sizeof(QNode));
s->rear->next = p;
(s)->rear = p;
(s)->rear->val = t;
(s)->rear ->next= NULL;
}
void dequeue(Queue *s, struct TreeNode **t) {
QNode *p;
(*t) = (s)->front->next->val;
p = (s)->front;
(s)->front=(s)->front->next;
free(p);
}
void main() {
int num[8] = { 3,2,1,6,0,5,10,20};
struct TreeNode* p,*q,*t; //定義樹節點
int count = 8;
Queue sq; //定義一個隊列
t = NULL;
struct TreeNode* temp = NULL;
//創建最大二叉樹
p = constructMaximumBinaryTree(num, count);
//printf("%d", p->val);
q = p;
//head=sq = NULL;
// sq->head = sq->rear;
//創建隊列頭結點,為空結點
sq.front = (QueuePtr)malloc(sizeof(QNode));
sq.rear = sq.front;
sq.rear->next = NULL;
//根節點入隊列
if (p != NULL)
{
enqueue(&sq, p );
}
count = 8;
//按層遍歷二叉樹
while ((sq.front)!=(sq.rear)&& count!=0)
{
dequeue(&sq,&t);
if (t != temp)
{
printf("%d ", (t)->val);
if ((t)->left != NULL)
{
enqueue(&sq, (t)->left);//左孩子入隊列
}
else
enqueue(&sq, temp);
if ((t)->right != NULL)
{
enqueue(&sq, (t)->right);
}
else
enqueue(&sq, temp);
count--;
}
else
printf("null ");
}
}