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