Given a binary tree, flatten it to a linked list in-place.

For example,
Given

         1
/ \
2 5
/ \ \
3 4 6

The flattened tree should look like:

   1
\
2
\
3
\
4
\
5
\
6

思路:

用先序遍历,得到的是从小到大的顺序。把先序遍历变形一下:

void flatten(TreeNode* root) {
if(NULL == root) return;
vector<TreeNode *> v;
v.push_back(root);
TreeNode * pCur = NULL;
TreeNode * p = NULL; while(!v.empty())
{
pCur = p = v.back();
while(NULL != p->left) //向左移动时只要把当前指针移动即可,因为是按照从小大的顺序的
{
v.push_back(p->left);
pCur = p = p->left;
} while(!v.empty() && (p = v.back()->right) == NULL) //找到下一个要处理的元素,一定是一个右子树
v.pop_back();
if(!v.empty())
v.pop_back(); if(p != NULL) //把待处理的右子树连在当前已经铺平的数的左子树上
{
v.push_back(p);
pCur->left = p;
}
} p = root;
while(p != NULL) //镜像,全部转移到右子树上
{
p->right = p->left;
p->left = NULL;
p = p->right;
}
}

我发现,我太依赖非递归了,其实有的时候用递归更好。比如大神的版本:

private TreeNode prev = null;

public void flatten(TreeNode root) {
if (root == null)
return;
flatten(root.right);
flatten(root.left);
root.right = prev;
root.left = null;
prev = root;
}

先把右子树放平,再把左子树放平。因为每次都先处理右子树,所以prev是数值从大到小的一个记录,每次prev都是恰比当前根节点大一点的那个指针的位置。(不大好理解)

下面这个,跟上面的思路很像,但是会容易理解很多:

public void flatten(TreeNode root) {
if (root == null) return; TreeNode left = root.left;
TreeNode right = root.right; root.left = null; flatten(left);
flatten(right); root.right = left;
TreeNode cur = root;
while (cur.right != null) cur = cur.right;
cur.right = right;
}

也是先铺平右子树,再铺平左子树。一定是右子树的值大于左子树,所以先把左子树连接到根节点右侧,再把右子树连在后面。 这个代码平铺左右子树的顺序没限制。反过来也行。

上面思路的非递归版本: 也是需要想半天才能看懂的。每次先把紧接着子树连好,其他代码都是从叶节点开始连接,这个是从根节点开始的。

public void flatten(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stk = new Stack<TreeNode>();
stk.push(root);
while (!stk.isEmpty()){
TreeNode curr = stk.pop();
if (curr.right!=null)
stk.push(curr.right);
if (curr.left!=null)
stk.push(curr.left);
if (!stk.isEmpty())
curr.right = stk.peek();
curr.left = null; // dont forget this!!
}
}

最新文章

  1. iOS网络3—UIWebView与WKWebView使用详解
  2. 你的指纹还安全吗? - BlackHat 2015 黑帽大会总结 day 2
  3. java万物皆对象
  4. Completely change MACE timestamps?
  5. BZOJ 1452: [JSOI2009]Count 二维树状数组
  6. USACO Section 2.2: Preface Numbering
  7. builder-设计模式
  8. idea maven web工程明明添加了maven lib的依赖,但启动web容器时始终报No Class Found?
  9. (简单) HDU 3308 LCIS,线段树+区间合并。
  10. elastalert基于微信公众号报警
  11. Sql Server 的服务器类型
  12. python程序爬虫总是崩溃
  13. java 中二维数组的定义和遍历
  14. 【转】Hibernate 配置
  15. ckplayer跨域调用
  16. day_6.10 tcp三次握手 四次挥手
  17. 阿里云Linux系统基线检查优化
  18. Beginning SDL 2.0(4) YUV加载及渲染
  19. Python os.popen() 方法
  20. tooltips插件

热门文章

  1. WebApi常见4xx错误总结!!!
  2. JavaWeb学习总结(五十)——文件上传和下载
  3. Elven Postman(BST )
  4. Bots(逆元,递推)
  5. hash-3.hashCode
  6. Android工程文件下assets文件夹与res文件夹的区别
  7. Android ListView 图片异步加载和图片内存缓存
  8. HDU 5122 K.Bro Sorting(2014北京区域赛现场赛K题 模拟)
  9. iOS开发——UI进阶篇(二)自定义等高cell,xib自定义等高的cell,Autolayout布局子控件,团购案例
  10. Unity3D引擎扩展中的编辑器定制方法