一次失败的面试

前几天,承蒙一位大龄哥哥看得起。让我去他所在的一家公司面试,去之前自己就已经定下目标了,坚持和面试官交谈10分钟就算胜利。没想到最后竟然坚持了2个半小时,然而这并没有什么卵用。题目并不难,现在看来,我紧张是我这次失利的一部分原因之外,自己在纸上写代码的能力不足也是一个方面。题目只有三道,有一个是非递归遍历遍历二叉树。这个的确是我写不出来,如果你不提示我用栈或者队列实现的话。剩余的2道都是一个正常的程序员应该写出来的。

1:变形的Fibonacci数列

假设有一数列A,A[]={ 1,2,5,7,5 }
当A>=2时,有A[i]=A[i-1]+A[i-2],特殊之处是:A[i-1],A[i-2]是数列A中的原始值。就是说:
A[3]=A[1]+A[2]=1+2=3
A[4]=A[2]+A[3]=2+5=7 //注意A[3]是原来的5 并不是上一步求和的3
以此类推
最终的数列A为:
A[]={1,2,3,7,12}
问题的关键就是,每次求和用的是前两次的原始值,但最终数列中保存的是新值。我语文不好,在这里描述的不清楚,请见谅。
所以程序的关键就是把原始值暂存起来。我写了一个简单的实现如下:

#include <iostream>
using namespace std;
int arr[6]={1,2,3,4,5,6 };
void sum(int arr[],int len){
  if(len<=2)
    return ;
  int temp1=arr[0],temp2=arr[1];
  int temp3=0;
  for(int i=2;i<len;i++){
    temp3=arr[i];
    arr[i]=temp2+temp1;
    temp1=temp2;
    temp2=temp3;
  }
}
void print(){
  for(int i=0;i<6;i++)
    cout<<arr[i]<<" ";
  cout<<endl;
}
int main(){
  cout<<"Befor Sum: "<<endl;
  print();
  sum(arr,6);
  cout<<"After Sum: "<<endl;
  print();
  return 0;
}

2:双向循环链表

第二道题目是,写一个双向循环链表。支持增加,删除操作。这个已经是老生常谈的问题了,所以我在这里也不用描述。直接实现了

#include <iostream>
using namespace std;
struct Node{
  int data;
  Node* prev;
  Node *next;
  Node(int val):data(val){
    prev=NULL;
    next=NULL;
  }
};

void insert(Node * &Root,Node *newNode){
  if(Root->prev==NULL && Root->next==NULL){
      Root->prev=newNode;
      Root->next=newNode;
      newNode->prev=Root;
      newNode->next=Root;
  }
  else{
    Node * temp=Root->prev;
    temp->next=newNode;
    newNode->prev=temp;
    Root->prev=newNode;
    newNode->next=Root;
  }
}

void deleteNode(Node *dNode){
  dNode->next->prev=dNode->prev;
  dNode->prev->next=dNode->next;
}

bool findAndDeleteNode(int val,Node *Root){
  Node* curNode=Root;
  do{
    if(curNode->data==val){
      deleteNode(curNode);
      return true;
    }
    curNode=curNode->next;
  }while(curNode!=Root);
  return false;   //没有找到
}
void printList(Node * list){
  Node *curNode=list;
  do{
    cout<<curNode->data<<endl;
    curNode=curNode->next;
  }while(curNode!=list);
}
//有一些特殊情况没有处理
int main(int argc,char **argv){
  Node *Root=NULL;
  Node *newNode=NULL;
  int val=-1;
  while(cin>>val){
    if(val==-1)
        break;
    if(Root==NULL)
        Root=new Node(val);
    else{
      newNode=new Node(val);
      insert(Root,newNode);
    }
  }
  cout<<"Enter the value that you want to delete: "<<endl;
  cin>>val;
  if(findAndDeleteNode(val,Root))
    cout<<"Delete is finished!"<<endl;
  else
    cout<<"This val is not exist in the List"<<endl;

  cout<<endl<<"Now the list is: "<<endl;
  printList(Root);
  return 0;
}

3:非递归遍历二叉树

递归遍历二叉树是很简单的,非递归遍历只需要解决其中一个关键的问题。怎么保存状态,因为递归遍历的时候不用关心这个。一个可行的解决办法是用一个栈来保存。幸好,C++ STL中有这个容器。至于思路,大家可以自己试着理解。网上教程也是数不胜数,这里就不再赘述。

#include <iostream>
#include <stack>
using namespace std;
struct Node{
  Node *lChild;
  Node *rChild;
  int val;
  Node(int value){
    val=value;
    lChild=nullptr;
    rChild=nullptr;
  }
};
bool check_if_equal(int val,int targetVal){
  if(val==targetVal){
    cout<<"I found this value."<<endl;
    return true;
  }
  return false;
}
void Pre(Node *Root){
    stack<Node*> s;
    Node *pcur=Root;
    //栈空 且 pcur==nullptr 说明 all node is visited
    while(pcur || !s.empty()){
      cout<<pcur->val<<" ";
      s.push(pcur);
      pcur=pcur->lChild;
      //stack is not empty and pcur is nullptr
      while(!pcur && !s.empty()){
        pcur=s.top();
        s.pop();
        pcur=pcur->rChild;
      }
    }
    cout<<endl;
}
void behind(Node *Root){
  Node *pprev=nullptr;
  Node *pcur=Root;
  stack<Node*> s;
  s.push(pcur);
  while(!s.empty()){
    pcur=s.top();
    if((pcur->lChild==nullptr && pcur->rChild==nullptr) ||
        (pprev!=nullptr && (pprev==pcur->rChild || pprev==pcur->lChild))){
            cout<<pcur->val<<" ";
            s.pop();
            pprev=pcur;
      }
    else{
      if(pcur->rChild!=nullptr)
         s.push(pcur->rChild);
      if(pcur->lChild!=nullptr)
        s.push(pcur->lChild);
    }
  }
  cout<<endl;
}
//非递归中序遍历
void inorderTravsersal(Node *Root){
  std::stack<Node*> s;
  Node *pcur=Root;
  while(pcur || !s.empty() ){
      if(pcur->lChild){
        s.push(pcur);
        pcur=pcur->lChild;
      }
      else{
        cout<<pcur->val<<" ";
        pcur=pcur->rChild;
        while(!pcur && !s.empty()){
          pcur=s.top();
          cout<<pcur->val<<" ";
          s.pop();
          pcur=pcur->rChild;
        }
      }
    }
    cout<<endl;
}
void insert(Node *root,int val){
  if(root->val<val){
    if(root->rChild==nullptr){
       root->rChild=new Node(val);
       return;
     }
    return insert(root->rChild,val);
  }
  if(root->val>val){
    if(root->lChild==nullptr){
      root->lChild=new Node(val);
      return;
    }
    return insert(root->lChild,val);
  }
}
int main(int argc,char **argv){
  Node *root=nullptr;
  int data=-1;
  while(cin>>data){
    if(data==-1)
        break;
    if(root==nullptr)
       root=new Node(data);
    else
      insert(root,data);
  }
  inorderTravsersal(root);
  Pre(root);
  behind(root);
  return 0;
}

以上就是所有内容

你可能感兴趣的:(递归,二叉树)