C語言實現最大二叉樹並按層遍歷



 

題目:給定一個不含重復元素的整數數組。一個以此數組構建的最大二叉樹定義如下:

  1. 二叉樹的根是數組中的最大元素。
  2. 左子樹是通過數組中最大值左邊部分構造出的最大二叉樹。
  3. 右子樹是通過數組中最大值右邊部分構造出的最大二叉樹。

通過給定的數組構建最大二叉樹,並且輸出這個樹的根節點。

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 ");
                            
    }
}






















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM