中序遍歷樹並判斷是否為二叉搜索樹


對給定的有N個節點(N>=0)的二叉樹,給出中序遍歷序列,並判斷是否為二叉搜索樹。

題目保證二叉樹不超過200個節點,節點數值在整型int范圍內且各不相同。

輸入格式:

第一行是一個非負整數N,表示有N個節點

第二行是一個整數k,是樹根的元素值

接下來有N-1行,每行是一個新節點,格式為r d e 三個整數,

r表示該節點的父節點元素值(保證父節點存在);d是方向,0表示該節點為父節點的左兒子,1表示右兒子;e是該節點的元素值

輸出格式:

首先輸出二叉樹的中序遍歷序列,每個元素占一行。對於空樹,不輸出任何內容。

然后如果給定的樹是二叉搜索樹,輸出Yes 否則輸出No

輸入樣例:

fig.jpg

對於圖片中的二叉樹:

3
20
20 0 10
20 1 25
 

輸出樣例:

10
20
25
Yes


代碼如下:
#include <malloc.h>
#include <stdio.h>
#include <string.h>

typedef struct BSTNode *BinTree;
struct BSTNode
{
    int data;
    BinTree left, right;
};

int a[205];
int len = 0;
BinTree create();    //創建空樹 
void InOrderTraversal (BinTree BT);    //中序遍歷
 

int main(){
    int n;    //結點數
    int k;    //樹根的元素值
    int flag = 0, flag1 = 0;
    scanf("%d", &n);
    if ( n==0 ){
        printf("Yes\n");
        return 0;
    }
    scanf("%d", &k);
    BinTree BT;
    BT = create();
    BT->data = k;
    int i; 
    for (i=0; i<n-1; i++){
        //r表示該節點的父節點元素值(保證父節點存在);
        //d是方向,0表示該節點為父節點的左兒子,1表示右兒子;
        //e是該節點的元素值
        int r, d, e;
        scanf("%d %d %d", &r, &d, &e);
        BinTree t = BT;
        if (r != t->data) { //搜索父結點 
            while (t->right){
                t = t->right;
                if (r == t->data){
                    flag1 = 1;
                    break;
                }
            }
            if (flag1 == 0) { 
                t = BT;
            } 
            while (t->left && flag1 == 0){
                t = t->left;
                if (r == t->data){
                    break;
                }
            }    
        }
        if ( d==0 ){
            t->left = create();
            t->left->data = e;
        }
        else if ( d==1 ){
            t->right = create();
            t->right->data = e;
        }
    }
    InOrderTraversal (BT);    //打印中序遍歷結果 
    for (i=1; i<len; i++){
        if (a[i-1]>=a[i]){
            flag = 1;
            break;
        }
    }
    if (flag == 0){
        printf("Yes\n");
    }
    else if (flag == 1){
        printf("No\n");
    }
    return 0;
}

BinTree create(){    //創建空樹/結點? 
    BinTree BT;
    BT = (BinTree)malloc(sizeof(struct BSTNode));
    BT->left = BT->right = NULL;
    return BT;
}

void InOrderTraversal (BinTree BT){    //中序遍歷
    if (BT){
        InOrderTraversal( BT->left );
        a[len++] = BT->data;
        printf("%d\n", BT->data);
        InOrderTraversal( BT->right );
    } 
}

其中:只有一個根結點也是二叉搜索樹

   二叉搜索樹的中序遍歷是從小到大輸出的,可以利用這個特點來判斷是否為二叉搜索樹

   搜索父結點的循環類似於暴力掃描,但是有缺陷,目前我找不出來,提交在PTA中測試點2未通過。原理:如果r不等於根節點的元素值,首先向右子樹遍歷,直到找到r等於結點元素值,修改flag1為1,跳出循環,如果右子樹未找到,令t重新回到根結點,再往左子樹遍歷。

 

在此貼上PTA的測試點

 

 

 







免責聲明!

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



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