1 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

# -*- coding:utf-8 -*-
# class TreeLinkNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#         self.next = None
class Solution:
    def GetNext(self, pNode):
        # write code here
        if not pNode:
            return None
        if pNode.right:
            pNode = pNode.right #别忘了先到右结点
            while pNode.left:
                pNode = pNode.left
            return pNode
        while pNode.next:
            pRoot = pNode.next
            if pRoot.left == pNode:
                return pRoot
            pNode = pNode.next
 #找规律,分三种情况讨论(评论区)

评论区思路:

链接:https://www.nowcoder.com/questionTerminal/9023a0c988684a53960365b889ceaf5e
来源:牛客网:首先知道中序遍历的规则是:左根右,然后作图

结合图,我们可发现分成两大类:1、有右子树的,那么下个结点就是右子树最左边的点;(eg:D,B,E,A,C,G) 2、没有右子树的,也可以分成两类,a)是父节点左孩子(eg:N,I,L) ,那么父节点就是下一个节点 ; b)是父节点的右孩子(eg:H,J,K,M)找他的父节点的父节点的父节点...直到当前结点是其父节点的左孩子位置。如果没有eg:M,那么他就是尾节点。

/*
struct TreeLinkNode {
int val;
struct TreeLinkNode *left;
struct TreeLinkNode *right;
struct TreeLinkNode *next;
TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) {
}
};
*/
//分析二叉树的下一个节点,一共有以下情况:
//1.二叉树为空,则返回空;
//2.节点右孩子存在,则设置一个指针从该节点的右孩子出发,一直沿着指向左子结点的指针找到的叶子节点即为下一个节点;
//3.节点不是根节点。如果该节点是其父节点的左孩子,则返回父节点;否则继续向上遍历其父节点的父节点,重复之前的判断,返回结果。
classSolution{
public:
    TreeLinkNode* GetNext(TreeLinkNode* pNode)
    {
        if (pNode == NULL)
            returnNULL;
        if (pNode->right != NULL)
        {
            pNode = pNode->right;
            while (pNode->left != NULL)
                pNode = pNode->left;
            returnpNode;
        }
        while (pNode->next != NULL)
        {
            TreeLinkNode *proot = pNode->next;
            if (proot->left == pNode)
                returnproot;
            pNode = pNode->next;
        }
        returnNULL;
    }
};

2 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isSymmetrical(self, pRoot):
        # write code here
        if not pRoot:
            return True
        return  self.compare(pRoot.left,pRoot.right)
    def compare(self,left,right):
        if not left and not right:
            return True
        if not left or not right:
            return False
        if left.val == right.val:
            if self.compare(left.left,right.right) and self.compare(left.left,right.right):
                return True #上一行很重要,要在代码中体现对称
        return False

 考察递归

3 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def Print(self, pRoot):
        # write code here
        # 选用栈解决
        if not pRoot:
            return []
        result = []      # 
        stack = [] #利用栈实现
        stack.append(pRoot)
        while stack:
            res = []   #储存下一行的值
            nextstack = [] #储存下一行的结点
            for i in stack: #遍历完这一行,包括添加结点与值
                res.append(i.val)
                if i.left:
                    nextstack.append(i.left)
                if i.right:
                    nextstack.append(i.right)
            stack = nextstack
            result.append(res)
        for i in range(len(result)): 偶数行要反转
            if i%2 == 1:
                result[i].reverse()
        return result
    '''大佬代码:链接:https://www.nowcoder.com/questionTerminal/91b69814117f4e8097390d107d2efbe0
来源:牛客网

class Solution:
    def Print(self, pRoot):
        if not pRoot:
            return []
        nodeStack=[pRoot]
        result=[]
        while nodeStack:
            res = []
            nextStack=[]
            for i in nodeStack:
                res.append(i.val)
                if i.left:
                    nextStack.append(i.left)
                if i.right:
                    nextStack.append(i.right)
            nodeStack=nextStack
            result.append(res)
        returnResult=[]
        for i,v in enumerate(result):
            if i%2==0:
                returnResult.append(v)
            else:
                returnResult.append(v[::-1])
        return returnResult

用一个队列存储,然后记得偶数行要反转(第一行k=0)

4 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回二维列表[[1,2],[4,5]]
    def Print(self, pRoot):
        # write code here
        if not pRoot:
            return []
        result = []
        queue = [pRoot]
        while queue:
            res = []
            nextqueue = []
            for i in queue:
                res.append(i.val) #是小括号!!
                if i.left:
                    nextqueue.append(i.left)
                if i.right:
                    nextqueue.append(i.right)
            result.append(res)
            queue = nextqueue
        return result

思路一样,注意输出的格式。(为空时也要注意输出格式)

5 请实现两个函数,分别用来序列化和反序列化二叉树

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def __init__(self):
        self.flag = -1
    def Serialize(self, root):
        # write code here
        self.res = []
        res1 = ''
        if not root:
            return '#,'
        self.mid(root)
        res1 = ','.join(self.res)
        return res1
    def mid(self,root): #前序遍历
        if not root:
            self.res.append('#')
            return
        self.res.append(str(root.val))
        self.mid(root.left)
        self.mid(root.right)
    def Deserialize(self, s):
        # write code here
        self.flag += 1
        l = s.split(',')
        root = None
        if l[self.flag] != '#':
            root = TreeNode(int(l[self.flag]))
            root.left = self.Deserialize(s)
            root.right = self.Deserialize(s)
        return root
                          
 #前序遍历可以直接找到根节点
     

考察前序遍历,递归法比较好做。注意join的用法,后面List必须是str才能连接。

6 给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8)    中,按结点数值大小顺序第三小结点的值为4。

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回对应节点TreeNode 
    #python解法,要注意,返回的是节点,而不是节点的值!!!尼玛,被坑了。!!!
    def KthNode(self, pRoot, k):
        # write code here
        if not k:
            return None
        self.res = []  #牢记self
        self.mid(pRoot)
        if k > len(self.res) or k < 0: #k的越界判断
            return None
        return self.res[k-1]
    def mid(self,root):  #递归实现
        if not root:
            return None
        self.mid(root.left)
        self.res.append(root)
        self.mid(root.right)
           

先递归实现中序遍历再返回指定的值即可,一定要注意的是,本题要求返回的是结点(root) 而不是结点的值(root.val)!!!root.val)!!!

7 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。

class Solution:
    def __init__(self):
        self.arr=[]
    def Insert(self, num):
        self.arr.append(num)
        self.arr.sort()
    def GetMedian(self,***):
        length=len(self.arr)
        return self.arr[length//2] if length%2==1 else (self.arr[length//2]+self.arr[length//2-1])/2.0
#注意self 学到的知识点
'''1、在python类中定义类变量时,
在__init__()函数中,通过self.variable_name 
定义
2、整数除以整数的结果为整数,如果想得到相除结果为
浮点数,则需要除以浮点数
self.l[length//2] + self.l[length//2 -1]) / 2
转换为
self.l[length//2] + self.l[length//2 -1]) / 2.0
--------------------- 
作者:cchangcs 
来源:CSDN 
原文:https://blog.csdn.net/github_39611196/article/details/88919102 
版权声明:本文为博主原创文章,转载请附上博文链接!'''

暴力法,注意要有self!

知识补充: 

1 数据流的中位数,可以用堆解决:

链接:https://www.nowcoder.com/questionTerminal/9be0172896bd43948f8a32fb954e1be1
来源:牛客网

插入有两种思路:

     * 1:直接插入大堆中,之后若两堆尺寸之差大于1(也就是2),则从大堆中弹出堆顶元素并插入到小堆中

     * 若两队之差不大于1,则直接插入大堆中即可。

     * 2:奇数个数插入到大堆中,偶数个数插入到小堆中,

     * 但是 可能会出现当前待插入的数比小堆堆顶元素大,此时需要将元素先插入到小堆,然后将小堆堆顶元素弹出并插入到大堆中

     * 对于偶数时插入小堆的情况,一样的道理。why?

     * 因为要保证最大堆的元素要比最小堆的元素都要小。

https://blog.csdn.net/u010005281/article/details/80327328 用堆解

2 python 中的堆 原理:https://www.cnblogs.com/kumata/p/9201571.html 用法:https://blog.csdn.net/u013206202/article/details/78968438

3 二叉搜索树的定义 https://blog.csdn.net/u013405574/article/details/51058133

4 中序遍历图解 https://blog.csdn.net/qq_33243189/article/details/80222629

5 三种遍历精讲 https://segmentfault.com/a/1190000016674584  python实现三种遍历 https://www.cnblogs.com/icekx/p/9127569.html

6 python中自带的栈与队列 https://www.cnblogs.com/yupeng/p/3413852.html

7 join方法文档 https://www.runoob.com/python/att-string-join.html

8 enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。>>>seq = ['one', 'two', 'three']

>>> for i, element in enumerate(seq):

... print i, element

0  one

1 two

2 three