1. 程式人生 > >03-樹2. List Leaves (25) Python C

03-樹2. List Leaves (25) Python C

03-樹2. List Leaves (25)

題目要求

Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N-1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a “-” will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each test case, print in one line all the leaves’ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

Sample Output:

4 1 5

題目分析

題目輸入序列第一列給出樹的節點個數N(N<=10);節點依次編號0~N-1;第一列之後個各個序列依次表示從0到N-1節點的左右子樹,存在即為子孩子的序號,不存在就用’-‘表示。
首先,根據輸入的資訊建樹,然後尋找根節點。尋找根節點的方法:用一個數組來標記每一個節點是否是其他節點的孩子節點,在輸入中出現過得肯定不是根節點,因為輸入的為節點左右孩子編號。
然後,從根開始層次遍歷,將葉子節點儲存,再按格式輸出即可。

C語言實現

@C語言實現參考了ice_camel的部落格,其C語言實現方式非常簡潔便於理解;另外我Python程式碼也根據此思想編寫的。

 /*
BY:jixiangruuri
DATE:2015.08.18
C語言
Nothing Replace Hard Word
*/
#include <stdio.h> #include <ctype.h> struct Node { int root; //記錄節點是否為根節點 int left; //左子樹 int right; //右子樹 }; int main(){ int n; //儲存節點個數 N <= 10 struct Node nodes[10]; scanf("%d",&n); //printf("%d",n); for(int i = 0; i < n; i++){//初始化樹節點 nodes[i].root = 1; //沒有連線的節點都是根節點 nodes[i].left = -1; //沒有左子樹 nodes[i].right = -1; //沒有右子樹 } for(int i = 0; i < n; i++){//構造樹 char ch1,ch2; scanf("\n%c %c",&ch1,&ch2); if(isdigit(ch1)){ //左子樹存在,將左子樹連線至該點 nodes[i].left = ch1 - '0'; //指標指向左子樹 nodes[ch1 - '0'].root = 0; //左子樹取消根節點標記 } if(isdigit(ch2)){ nodes[i].right = ch2 - '0'; nodes[ch2 - '0'].root = 0; } } int root; //根節點序號 for(int i = 0; i < n; i++) if(nodes[i].root == 1){ root = i; break; } //構造完樹後,層序遍歷樹,依次輸出葉子節點;層序遍歷:從根節點開始依次將左右兒子入隊,直至佇列為空 int leaves = 0; //記錄輸出葉節點的個數 int queue[10]; //節點佇列,只儲存節點下標 int head = 0, rear = 0; queue[rear++] = root; //根節點入隊 while(rear - head){ int node = queue[head++]; //隊首節點出隊 if(nodes[node].left == -1 && nodes[node].right == -1){ if(leaves) //輸出第一個時,不輸出空格 printf(" "); printf("%d",node); ++leaves; } if(nodes[node].left != -1) //如果存在,左子樹入隊 queue[rear++] = nodes[node].left; if(nodes[node].right != -1) //如果存在,右子樹入隊 queue[rear++] = nodes[node].right; } return 0; }

Python實現

#! /usr/bin/env python
# -*- coding: utf-8 -*-

'''
BY:jixiangrurui
DATE:2015.08.19
Python:3.4.3
Nothing Replaces Hard Work
'''

def FindLeaves(seq,root):
    '''(list of list of int, int) -> tuple of int

    Return the tree's leaves node in a tuple

    >>> seq = [[0, 1, -1], [0, -1, -1], [0, 0, -1], [1, 2, 7], [0, -1, -1], [0, -1, -1], [1, 5, -1], [1, 4, 6]]   # [是否為根節點,左子樹,右子樹]
    >>> root = 3
    >>> FindLeaves(seq,root)
    [4, 1, 5]
    >>> seq = [[0, 4, -1], [0, 2, 7], [0, -1, -1], [0, -1, -1], [0, -1, -1], [1, 1, 6], [0, 0, 3], [0, -1, 8], [0, 9, -1], [0, -1, -1]]
    >>> root = 5
    >>> FindLeaves(seq,root)
    [2,3,4,9]
    '''
    result = []
    queue = []
    queue.append(root)
    while(len(queue) >0 ):
        node = queue.pop(0)
        if(seq[node][1] == -1 and seq[node][2] == -1):
            result.append(node)
        if(seq[node][1] != -1):
            queue.append(seq[node][1])
        if(seq[node][2] != -1):
            queue.append(seq[node][2])

    return result 



if __name__ == '__main__':
    # 輸入資料
    n = int(input()) # 節點長度
    strs = []        # 接收樹結構資訊 
    for i in range(n):
       strs.append(input().split(" "))
    # 初始化樹
    seq = []
    for i in range(n):    # 初始化樹[根節點,左子樹,右子樹]:是根節點為1,不是為0;左右子樹,存在即為相應的序號,不存在為-1
        seq.append([1,-1,-1])
    for i in range(n):
        if(strs[i][0] != '-'):
            seq[i][1] = int(strs[i][0])
            seq[int(strs[i][0])][0] = 0
        if(strs[i][1] != '-'):
            seq[i][2] = int(strs[i][1])
            seq[int(strs[i][1])][0] = 0
    # 尋找根節點
    for i in range(n):
        if(seq[i][0] == 1):
            root = i
            break
    # 查詢葉子節點
    result = FindLeaves(seq,root)
    for i in range(len(result)-1):
        print(result[i],end=" ")
    print(result[len(result)-1])

這裡寫圖片描述