C++校招筆試題,BAT內部流出(2)

1.已知兩個鏈表head1 和head2 各自有序,請把它們合併成一個鏈表依然有序。(保留所有結點,即便大小相同)

     給定鏈表的結點結構如下:

struct Node
{
int data ;
Node *next ;
};

答案:

Node * Merge(Node *head1 , Node *head2)
{
    if ( head1 == NULL)
        return head2 ;

    if ( head2 == NULL)
        return head1 ;

    Node *head = NULL;
    Node *p1 = NULL;
    Node *p2 = NULL;
    if ( head1->data < head2->data )
    {
        head = head1 ;
        p1 = head1->next;
        p2 = head2 ;

    }
    else
    {
        head = head2 ;
        p2 = head2->next ;
        p1 = head1 ;
    }


    Node *pcurrent = head ;
    while ( p1 != NULL && p2 != NULL)
    {

        if ( p1->data <= p2->data )
        {
            pcurrent->next = p1 ;
            pcurrent = p1 ;
            p1 = p1->next ;
        }
        else
        {
            pcurrent->next = p2 ;
            pcurrent = p2 ;
            p2 = p2->next ;
        }
    }

    if ( p1 != NULL )
        pcurrent->next = p1 ;


    if ( p2 != NULL )
        pcurrent->next = p2 ;

    return head ;
}

2.寫一函數檢測單向鏈表是否存在環,要求時間複雜度爲O(n),並只使用常量空間。注意:只知道一個指向單向鏈表頭的指針,要求不允許破壞原始鏈表結構。

答案:

bool HasCircle(ListNode * pHead)
{
   ListNode * pFast = pHead; // 快指針每次前進兩步
   ListNode * pSlow = pHead; // 慢指針每次前進一步

   while(pFast != NULL && pFast->m_pNext != NULL)
   {
       pFast = pFast->m_pNext->m_pNext;
       pSlow = pSlow->m_pNext;

       if (pSlow == pFast) // 相遇,存在環
           return true;

   }

   return false;
}

3.編寫一個函數,作用是把一個char組成的字符串循環右移n個。比如原來是“abcdefghi”如果n=2,移位後應該是“hiabcdefgh”。

答案:

void LoopMove ( char *pStr, int steps )
{
    steps = steps % strlen(pSstr);  //考慮steps大於數組長度
    int n = strlen( pStr ) - steps; 

    char * tmp = NULL;
    tmp = (char *)malloc( strlen( pStr ) + 1 );
    if (tmp == NULL)
    {
        printf("Malloc Error\n");
        return;
    }
    memset(tmp,0, len+1);

    memcpy( tmp, pStr + n, steps ); 
    memcpy(pStr + steps, pStr, n ); 
    memcpy(pStr, tmp, steps ); 
}

4.請使用棧實現隊列的入隊和出隊操作。

答案:

template<typename T>
class Queue
{
public:
    void Enqueue(T x) // 入隊列,元素爲x
    {
      s1.push(x);
    }

    void Dequeue(T& x) //出隊列,將隊頭元素賦值給x
    {
        if(s2.empty())
        {
            while( ! s1.empty() )
            {
                s2.push( s1.pop() );
            }
        }

        if( s2.empty() )
        {
            printf("Empty!\n");
            return;
        }

        x = s2.pop();
}

private:
    std::stack<T> s1;
    std::stack<T> s2;

};

5.寫一函數,判定二叉樹是否是有序二叉樹。

答案:

typedef struct node  
{  
    int data;  
    struct node *lchild,*rchild;  
}Bitree;

int IsSearchTree(const Bitree *t) //遞歸遍歷二叉樹是否爲二叉排序樹
{  
    if(!t)                                  //空二叉樹情況 
        return 1;  
    else if(!(t->lchild) && !(t->rchild))          //左右子樹都無情況  
        return 1;  
    else if((t->lchild) && !(t->rchild))           //只有左子樹情況  
    {  
        if(t->lchild->data>t->data)  
            return 0;  
        else  
            return IsSearchTree(t->lchild);  
    }  
    else if((t->rchild) && !(t->lchild))           //只有右子樹情況  
    {  
        if(t->rchild->data<t->data)  
            return 0;  
        else  
            return IsSearchTree(t->rchild);  
    }  
    else                                  //左右子樹全有情況  
    {                                  
        if((t->lchild->data>t->data) || (t->rchild->data<t->data))  
            return 0;  
        else  
            return (IsSearchTree(t->lchild) && IsSearchTree(t->rchild) );  
    }  
}  

6.用C++寫出單鏈表逆置的遞歸實現與迭代實現。

答案:

//迭代實現:
void reverse(Node*& head) 
{
    if (!head) return;
    Node* prev = NULL;
    Node* curr = head;
    while (curr) 
    {
        Node* next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    head = prev;
}

// 遞歸實現:
void reverse(Node*& p) 
{
    if (!p) 
        return;
    Node* rest = p->next;
    if (!rest)
        return;
    reverse(rest);
    p->next->next = p;
    p->next = NULL;
    p = rest;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章