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;
}

 

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