【问题标题】:Convert a BST into preorder and postorder linkedlists将 BST 转换为前序和后序链表
【发布时间】:2014-07-25 17:43:09
【问题描述】:

这是第 2 轮亚马逊面试问题。将给定的二叉搜索树转换为预排序和后排序链接列表,并且此转换必须就地

【问题讨论】:

    标签: linked-list binary-search-tree in-place preorder postorder


    【解决方案1】:

    下面的代码是为了在不使用堆栈的情况下以 pre-Order 遍历形式对二叉树进行展平。它使用前序遍历递归方法。在此, TreeNode[] arr 将保存最后一个最左边的节点值,我正在更新该节点的右指针。

        public TreeNode preorderNode(TreeNode root,TreeNode[] arr)
        {
        if(root==null)
            return null;
        if(root!=null && root.left==null && root.right==null)    
            {
                arr[0]=root;
                return root;
            }
        TreeNode temp=root.right;
        if(root.left!=null)
            root.right=preorderNode(root.left,arr);
        else arr[0]=root;
        root.left=null;
        arr[0].right=preorderNode(temp,arr);
        return root;
        }
        public void flatten(TreeNode root) {
    
            if(root==null || (root.left==null && root.right==null))
                return;
            TreeNode temp=root.right;    
            TreeNode[] arr=new TreeNode[1];
            arr[0]=null;
            if(root.left!= null)
                root.right=preorderNode(root.left,arr);
            else
                arr[0]=root;
            root.left=null;
           arr[0].right=preorderNode(temp,arr);
       }
    

    【讨论】:

      【解决方案2】:

      为了解决预购版的问题,你可以稍微修改一个简单的预购(参考下面的代码看看)。

      这个想法是在前序遍历中从二叉搜索树构造一个双向链表。但是,我们只在遍历过程中设置了前向链接。

      让我们通过一个例子来学习。 如果树看起来像:

              4
             / \
            2   6
           / \ / \
          1  3 5  7
      

      那么,链表应该是这样的:

      4 2 1 3 6 5 7.

      现在,我们只在前序遍历期间设置前向链接。因此,我们的列表将如下所示。

      4 -> 2 -> 1 -> 3 -> 6 -> 5 -> 7

      左边或前面的指针(上面未显示)仍然与树中的一样。 我们现在可以通过简单的遍历列表来设置左指针。

      下面的代码正是这样做的。

      #include <iostream>
      using namespace std;
      
      class node{
          public:
              int data;
              node * left, *right;
              node(int a){
                  data = a;
                  left = right = NULL;
              }
      };
      
      node * head = NULL, *prev = NULL;
      
      void preorder(node * root){
          if(!root)   return;
      
          //both head and prev aren't set. This node must be the root(and head of our required list).
          if(!head and !prev) head = root;    
      
          //store the address of root's right child
          node * temp = root->right;
      
          /*
              If prev is set, make current node it's right child.
              (This is why we save right child's address for every node in temp.)
          */
          if(prev)    prev->right = root;
      
          //now make the current node prev.
          prev = root;
          cout << root ->data <<" ";
      
          preorder(root->left);
          preorder(temp);
      }
      
      void printll(){
          node * prev = NULL;
          while(head != NULL){
              cout << head ->data << " ";
              head -> left = prev;
              head = head -> right;
              prev = head;
          }
          cout<<endl;
      }
      
      int main() {
      
          node * t = new node(4);
      
          t->left = new node(2);
          t->left->left = new node(1);
          t->left->right = new node(3);
      
          t->right = new node(6);
          t->right->left = new node(5);
          t->right->right = new node(7);
      
          preorder(t);
          cout<<endl;
          printll();
          return 0;
      }
      

      【讨论】:

        【解决方案3】:
        void preorder(struct node *head)
        {
        
        if (head)
            {
                addToLL(head->data);
                preorder(head->left);
                preorder(head->right);
            }
        }
        

        在 addToLL() 中,您可以继续将节点添加到链表中。

        全球宣言

        struct node *llHead;
        

        这样链表头就完好无损。

        【讨论】:

        • 我们必须就地转换它
        【解决方案4】:

        以下算法用于预购转换。同样,您可以进行后订购。

         struct node
            {
                int data;
                struct node* left;
                struct node* right;
            };
        
            /Algorithm */
            struct node* bintree2listHelper(struct node *root)
            {
               if (root == NULL)
                  return root;
        
               if (root->left != NULL)
               {
                  struct node* left = bintree2listHelper(root->left);
        
                  int flag =0;
             if(left->left == NULL)
            {
               left->left = left->right;
            }
        
        
        
                  for(;left->left != NULL;)
                  {
                     struct node *temp = left;
        
                     for (; temp->right!=NULL; )
                     {
                        flag = 1;
                        temp=temp->right;
                     }
                     if(flag)
                     {
                        temp->left = root->right;
                        left =left->left;
                        break;
                     }
                     else
                     {
                        left =left->left;
                     }
        
                  }
        
                  if(!flag)
                     left->left = root->right;
               }
        
               if (root->right!=NULL)
               {
                  struct node* right = bintree2listHelper(root->right);
        
                  struct node *temp1= right;
        
                  for (; right->left!=NULL; )
                  {
                     temp1 =right;
                     right = right->left;
                  }
        
        
                  right->left = temp1->right;
               }
               return root;
            }
        
            struct node* bintreeTolist(struct node *root)
            {
                if (root == NULL)
                    return root;
        
                root = bintree2listHelper(root);
        
                return (root);
            }
        
            struct node* newNode(int data)
            {
                struct node* new_node = (struct node *)malloc(sizeof(struct node));
                new_node->data = data;
                new_node->left = new_node->right = NULL;
                return (new_node);
            }
        
            void printList(struct node *node)
            {
                while (node!=NULL)
                {
                    printf("%d ", node->data);
                    node = node->left;
                }
                printf("\n");
            }
        int main()
        {
            typedef struct node node;
            node *root        = newNode(10);
            root->left        = newNode(12);
            root->right       = newNode(15);
            root->left->left  = newNode(25);
            root->left->right = newNode(30);
            root->right->left = newNode(36);
            root->left->right->left = newNode(78);
            root->left->right->right = newNode(77);
         node *head = bintreeTolist(root);
        
            // Print the converted list
        
           printList(head);
        return 0;
        

        【讨论】:

          【解决方案5】:

          预购链表

           public TreeNode flatten(TreeNode root) {
              if(root==null)
                  return null;
              Stack<TreeNode> s=new Stack<TreeNode>();
              s.add(root);
              while(!s.isEmpty()){
                  root=s.pop();
                  if(root.right!=null)
                      s.add(root.right);
                  if(root.left!=null)
                      s.add(root.left);
                  if(!s.isEmpty())
                      root.right=s.peek();
                  else
                      root.right=null;
                  root.left=null;
              }
              return root;
           }
          

          上面的代码给出了右指针作为下一个指针的前序链表,左指针被忽略(即设置为空)。它是对迭代前序遍历代码的轻微修改。
          思路是一旦当前节点的处理完成,栈顶就有链表中当前节点的下一个节点。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多