把二元查找树转变成排序的双向链表(微软面试)
2014-05-30 22:42
423 查看
把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
思路:
建立一个head头节点(指向现在双向队列的头节点),一个tail尾节点(指向双向队列的尾节点)
中序遍历来更新和维护头节点与尾节点
遍历到的节点node时,
1,让该node的左节点指向tail尾节点
2, 若head=null时,则head=node
否则,将该节点加入到双向队列中,尾节点tail的右节点指向该节点node
3, 更新尾节点指向到该node
这里有两个版本一个Java,一个C++
我写了java版,C++版是从其他地方Copy的
因为java没有指针在操作节点时不太方便,本来采取递归的,当时由于java的值传递,操作时没有在外面更新。
最后采取中序遍历,每个节点操作,并维护头节点和尾节点。
有问题的话,麻烦读者指正。
java版
#Node.class
#BinaryTree.java
/**
执行结果:
C++版
///////////////////////////////////////////////
4
6
8
10
12
14
15
16
Press any key to continue
//////////////////////////////////////////////
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
思路:
建立一个head头节点(指向现在双向队列的头节点),一个tail尾节点(指向双向队列的尾节点)
中序遍历来更新和维护头节点与尾节点
遍历到的节点node时,
1,让该node的左节点指向tail尾节点
2, 若head=null时,则head=node
否则,将该节点加入到双向队列中,尾节点tail的右节点指向该节点node
3, 更新尾节点指向到该node
这里有两个版本一个Java,一个C++
我写了java版,C++版是从其他地方Copy的
因为java没有指针在操作节点时不太方便,本来采取递归的,当时由于java的值传递,操作时没有在外面更新。
最后采取中序遍历,每个节点操作,并维护头节点和尾节点。
有问题的话,麻烦读者指正。
java版
#Node.class
public class Node { private Node left; private Node right; private int key; public Node() { } public Node(int key) { this.key = key; } public int getKey() { return key; } public Node getLeft() { return left; } public Node getRight() { return right; } public void setKey(int key) { this.key = key; } public void setLeft(Node left) { this.left = left; } public void setRight(Node right) { this.right = right; } }</span>
#BinaryTree.java
/**
* 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 * 要求不能创建任何新的结点,只调整指针的指向。 * 10 * / \ * 6 14 * / \ / \ * 4 8 12 16 * * 转换成双向链表 * 4<=>6<=>8<=>10<=>12<=>14<=>16。 * * @author heen * * @version 1.0 2014.5.30 */ public class BinaryTree { private static Node root; private static int size; private static Node pHead = new Node(); private static Node pTail = new Node(); public BinaryTree(Node node) { this.root = node; size = 1; } /** * Run configbation 输入数据 5 1 8 2 7 * */ public static void main(String[] args) { int n = args.length; int[] inputArray = new int ; // 把输入的数据转化为int型的数组 for (int i = 0; i < n; i++) { inputArray[i] = Integer.parseInt(args[i]); System.out.print(inputArray[i]); } System.out.println(); // 二叉树增加节点 for (int i = 0; i < n; i++) { Node node = new Node(inputArray[i]); addNode(node); } System.out.println("BinaryTree Size:" + size); System.out.println("***********二叉树中序遍历**************"); // 中序调整节点,使二叉树调整为双向链表 inorderAdjust(root); System.out.println("***********双向链表遍历**************"); doubleLinkedList(); } /** * 双向链表遍历 */ public static void doubleLinkedList() { while (pHead != null) { System.out.println("node:" + pHead.getKey()); pHead = pHead.getRight(); } } /** * 中序遍历 * * @param node */ private static void inorderAdjust(Node node) { if (node == null) return; inorderAdjust(node.getLeft()); convertToDoubleList(node); inorderAdjust(node.getRight()); } /** * 树转化为双向链表 * * 将中序遍历的节点加入到队尾,并调整队尾到新节点处 * * @param node */ private static void convertToDoubleList(Node node) { node.setLeft(pTail); if (pTail.getKey() != 0) { pTail.setRight(node); } else pHead = node; pTail = node; System.out.println("Node:" + node.getKey()); } /** * 增加节点,当root为null时,就把root赋值为该node * 否则按规则加入二叉树 * @param node */ private static void addNode(Node node) { if (root == null){ size++; root = node; } else addNode(root, node); } /** * 按规则给二叉树增加节点 * * 右节点不小于所有左节点, * 左节点不大于所有右节点 * * @param node * */ private static Node addNode(Node root, Node node) { if (root == null) { size++; return node; } if (node.getKey() >= root.getKey()) root.setRight(addNode(root.getRight(), node)); else root.setLeft(addNode(root.getLeft(), node)); return root; } }</span><span style="font-size:14px;"> </span>
执行结果:
C++版
#include <stdio.h> #include <iostream.h> struct BSTreeNode { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; typedef BSTreeNode DoubleList; DoubleList * pHead; DoubleList * pListIndex; void convertToDoubleList(BSTreeNode * pCurrent); // 创建二元查找树 void addBSTreeNode(BSTreeNode * & pCurrent, int value) { if (NULL == pCurrent) { BSTreeNode * pBSTree = new BSTreeNode(); 3 pBSTree->m_pLeft = NULL; pBSTree->m_pRight = NULL; pBSTree->m_nValue = value; pCurrent = pBSTree; } else { if ((pCurrent->m_nValue) > value) { addBSTreeNode(pCurrent->m_pLeft, value); } else if ((pCurrent->m_nValue) < value) { addBSTreeNode(pCurrent->m_pRight, value); } else { //cout<<"重复加入节点"<<endl; } } } // 遍历二元查找树中序 void ergodicBSTree(BSTreeNode * pCurrent) { if (NULL == pCurrent) { return; } if (NULL != pCurrent->m_pLeft) { ergodicBSTree(pCurrent->m_pLeft); } // 节点接到链表尾部 convertToDoubleList(pCurrent); // 右子树为空 if (NULL != pCurrent->m_pRight) { ergodicBSTree(pCurrent->m_pRight); } } 4 // 二叉树转换成list void convertToDoubleList(BSTreeNode * pCurrent) { pCurrent->m_pLeft = pListIndex; if (NULL != pListIndex) { pListIndex->m_pRight = pCurrent; } else { pHead = pCurrent; } pListIndex = pCurrent; cout<<pCurrent->m_nValue<<endl; } int main() { BSTreeNode * pRoot = NULL; pListIndex = NULL; pHead = NULL; addBSTreeNode(pRoot, 10); addBSTreeNode(pRoot, 4); addBSTreeNode(pRoot, 6); addBSTreeNode(pRoot, 8); addBSTreeNode(pRoot, 12); addBSTreeNode(pRoot, 14); addBSTreeNode(pRoot, 15); addBSTreeNode(pRoot, 16); ergodicBSTree(pRoot); return 0; }</span>
///////////////////////////////////////////////
4
6
8
10
12
14
15
16
Press any key to continue
//////////////////////////////////////////////
相关文章推荐
- 微软面试100之1 把二元查找树转变成排序的双向链表(树)
- 把二元查找树转变成排序的双向链表(JULY微软面试100题系列第一题)的算法思考
- 微软面试100题 第一题 把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表(微软面试题)
- 把二元查找树转变成排序的双向链表——精选微软经典的算法面试100题中第一题
- 微软面试(1/100)---把二元查找树转变成排序的双向链表
- 微软等数据结构+算法面试100题(43)-- 把二元查找树转变成排序的双向链表
- 1. 微软面试题:把二元查找树转变成排序的双向链表(树)
- 【微软100题】001把二元查找树转变成排序的双向链表(树)
- 1.把二元查找树转变成排序的双向链表(树)
- 微软面试题系列(一):把二元查找树转变成排序的双向链表
- 【微软100面试题实现】第01题:把二元查找树转变成排序的双向链表
- 1.把二元查找树转变成排序的双向链表
- 面试100题:1.把二元查找树转变成排序的双向链表
- 把二元查找树转变成排序的双向链表(树)
- 微软等面试100题筛选答案-1-二元查找树转换成一个排序的双向链表
- 把二元查找树转变成排序的双向链表
- 微软100题(1) 二元查找树转变成排序的双向链表
- No1、把二元查找树转变成排序的双向链表(树)
- 面试___把二元查找树转变成排序的双向链表