前几天,承蒙一位大龄哥哥看得起。让我去他所在的一家公司面试,去之前自己就已经定下目标了,坚持和面试官交谈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;
}
以上就是所有内容