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