您的位置:首页 > 编程语言

编程题——21~30

2016-07-22 00:00 363 查看
摘要: 通过《剑指offer》学习(复习)编程基础

二十一、包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,调

用min、push及pop的时间复杂度都是O(1)。

/*
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。在该栈中,
调用min、push及pop的时间复杂度都是O(1)。
*/

#include <iostream>
#include <stack>
#include <assert.h>
#include <stdio.h>

template <typename T> class StackWithMin
{
public:
StackWithMin( void ) { }
virtual ~StackWithMin( void ) { }

T& top( void );
const T& top( void ) const;

void push( const T& value );
void pop( void );

const T& min( void ) const;

bool empty() const;
size_t size() const;

private:
std::stack<T> m_data;
std::stack<T> m_min;
};

template<typename T> void StackWithMin<T>::push( const T& value )
{
m_data.push( value );

if( m_min.size() == 0 || value < m_min.top() )
m_min.push( value );
else
m_min.push( m_min.top() );
}

template <typename T> void StackWithMin<T>::pop()
{
assert( m_data.size() > 0 && m_min.size() > 0 );

m_data.pop();
m_min.pop();
}

template<typename T> const T& StackWithMin<T>::min() const
{
assert( m_data.size() > 0 && m_min.size() > 0 );

return m_min.top();
}

template<typename T> T& StackWithMin<T>::top()
{
return m_data.top();
}

template<typename T> const T& StackWithMin<T>::top() const
{
return m_data.top();
}

template<typename T> bool StackWithMin<T>::empty() const
{
return m_data.empty();
}

template<typename T> size_t StackWithMin<T>::size() const
{
return m_data.size();
}

void Test( const char* testName, const StackWithMin<int>& stack, int expected )
{
if( testName != NULL )
printf( "%s begins: ", testName );

if( stack.min() == expected )
printf( "Passed.\n" );
else
printf( "Failed.\n" );
}

int main()
{
StackWithMin<int> stack;

stack.push( 3 );
Test( "Test1", stack, 3 );

stack.push( 4 );
Test( "Test2", stack, 3 );

stack.push( 2 );
Test( "Test3", stack, 2 );

stack.push( 3 );
Test( "Test4", stack, 2 );

stack.pop();
Test( "Test5", stack, 2 );

stack.pop();
Test( "Test6", stack, 3 );

stack.pop();
Test( "Test7", stack, 3 );

stack.push( 0 );
Test( "Test8", stack, 0 );

}




二十二、栈的压入、弹出序列

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺

序。假设压入栈假设压入栈的所有数字均不相等。例如序列1、2、3 、4、5是某栈的压栈序

列,序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压

栈序列的弹出序列。

#include <iostream>
#include <stdio.h>
#include <stack>

bool IsPopOrder( const int* pPush, const int* pPop, int nLength )
{
bool bPossible = false;

if( pPush != NULL && pPop != NULL && nLength > 0 )
8000

{
const int* pNextPush = pPush;
const int* pNextPop = pPop;

std::stack<int> stackData;

while( pNextPop - pPop < nLength )
{
while( stackData.empty() || stackData.top() != *pNextPop )
{
if( pNextPush - pPush == nLength )
break;

stackData.push( *pNextPush );

pNextPush++;
}

if( stackData.top() != *pNextPop )
break;

stackData.pop();
pNextPop++;
}

if( stackData.empty() && pNextPop - pPop == nLength )
bPossible = true;
}

return bPossible;
}

void Test( const char* testName, const int* pPush, const int* pPop, int nLength, bool expected )
{
if( testName != NULL )
printf( "%s begins: ", testName );

if( IsPopOrder( pPush, pPop, nLength ) == expected )
printf( "Passed.\n" );
else
printf( "failed.\n" );
}

void Test1()
{
const int nLength = 5;
int push[ nLength ] = { 1, 2, 3, 4, 5 };
int pop[ nLength ] = { 4, 5, 3, 2, 1 };

Test( "Test1", push, pop, nLength, true );
}

void Test2()
{
const int nLength = 5;
int push[ nLength ] = { 1, 2, 3, 4, 5 };
int pop[ nLength ] = { 4, 3, 5, 1, 2 };

Test( "Test2", push, pop, nLength, true );
}

void Test3()
{
const int nLength = 5;
int push[ nLength ] = { 1, 2, 3, 4, 5 };
int pop[ nLength ] = { 3, 5, 4, 1, 2 };

Test( "Test3", push, pop, nLength, true );
}

void Test4()
{
const int nLength =1;
int push[ nLength ] = { 1 };
int pop[ nLength ] = { 3 };

Test( "Test4", push, pop, nLength, true );
}

int main()
{
Test1();
Test2();
Test3();
Test4();

return 0;
}




二十三、从上往下打印二叉树

从上往下打印出二叉树的每个结点,同一层的结点按照从左到右的顺序打印。

#include <iostream>
#include <stdio.h>
#include <deque>

struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};

BinaryTreeNode* CreateBinaryTreeNode( int value )
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = NULL;
pNode->m_pRight = NULL;

return pNode;
}

void ConnectTreeNodes( BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight )
{
if( pParent != NULL )
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
}
}

void PrintTreeNode( BinaryTreeNode* pNode )
{
if( pNode != NULL )
{
printf( "value of this node is: %d\n", pNode->m_nValue );

if( pNode->m_pLeft != NULL )
printf( "value of its left child is: %d.\n", pNode->m_pLeft->m_nValue );
else
printf( "left child is null.\n" );

if( pNode->m_pRight != NULL )
printf( "value of its right child is: %d.\n", pNode->m_pRight->m_nValue );
else
printf( "right child is null.\n" );
}
else
{
printf( "this node is null.\n" );
}

printf( "\n" );
}

void PrintTree( BinaryTreeNode* pRoot )
{
PrintTreeNode( pRoot );

if( pRoot != NULL )
{
if( pRoot->m_pLeft != NULL )
PrintTree( pRoot->m_pLeft );

if( pRoot->m_pRight != NULL )
PrintTree( pRoot->m_pRight );
}
}

void DestroyTree( BinaryTreeNode* pRoot )
{
if( pRoot != NULL )
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;

delete pRoot;
pRoot = NULL;

DestroyTree( pLeft );
DestroyTree( pRight );
}
}

void PrintFromTopToBottom( BinaryTreeNode* pTreeRoot )
{
if( !pTreeRoot )
return;

std::deque<BinaryTreeNode *> dequeTreeNode;

dequeTreeNode.push_back( pTreeRoot );

while( dequeTreeNode.size() )
{
BinaryTreeNode *pNode = dequeTreeNode.front();
dequeTreeNode.pop_front();

printf( "%d ", pNode->m_nValue );

if( pNode->m_pLeft )
dequeTreeNode.push_back( pNode->m_pLeft );

if( pNode->m_pRight )
dequeTreeNode.push_back( pNode->m_pRight );
}
}

// 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
//            8
//        6      10
//       5 7    9  11
void Test1()
{
printf( "\n=====Test1 starts:=====\n" );
BinaryTreeNode* pNode8 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 );
BinaryTreeNode* pNode10 = CreateBinaryTreeNode( 10 );
BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 );
BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 );
BinaryTreeNode* pNode9 = CreateBinaryTreeNode( 9 );
BinaryTreeNode* pNode11 = CreateBinaryTreeNode( 11 );

ConnectTreeNodes( pNode8, pNode6, pNode10 );
ConnectTreeNodes( pNode6, pNode5, pNode7 );
ConnectTreeNodes( pNode10, pNode9, pNode11 );

PrintTree( pNode8 );

printf( "\n=====Test1: PrintFromTopToBottom=====\n" );
PrintFromTopToBottom( pNode8 );

printf( "\n" );

DestroyTree( pNode8 );
}

// 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
//            8
//          7
//        6
//      5
//    4
void Test2()
{
printf( "\n=====Test2 starts:=====\n" );
BinaryTreeNode* pNode8 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 );
BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 );
BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 );
BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 );

ConnectTreeNodes( pNode8, pNode7, NULL );
ConnectTreeNodes( pNode7, pNode6, NULL );
ConnectTreeNodes( pNode6, pNode5, NULL );
ConnectTreeNodes( pNode5, pNode4, NULL );

PrintTree( pNode8 );

printf( "\n=====Test2: PrintFromTopToBottom=====\n" );
PrintFromTopToBottom( pNode8 );

printf( "\n" );

DestroyTree( pNode8 );
}

int main()
{
Test1();
Test2();

return 0;
}



二十四、二叉搜索树的后序遍历

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回

true,否则返回false。假设输入的数组的任何两个数字都互不相同。

#include <iostream>
#include <stdio.h>

bool VerifySquenceOfBST( int sequence[], int length )
{
if( sequence == NULL || length <= 0 )
return false;

int root = sequence[ length - 1 ];

// 在二叉搜索树中左子树的结点小于根节点
int i = 0;
for( ; i < length - 1; ++i )
{
if( sequence[ i ] > root )
break;
}

// 在二叉搜索树中右子树的结点大于根结点
int j = i;
for( ; j < length - 1; ++j )
{
if( sequence[ j ] < root )
return false;
}

// 判断左子树是不是二叉搜索树
bool left = true;
if( i > 0 )
left = VerifySquenceOfBST( sequence, i );

// 判断右子树是不是二叉搜索树
bool right = true;
if( i < length - 1 )
right = VerifySquenceOfBST( sequence + i, length - i - 1 );

return ( left && right );
}

void Test( const char* testName, int sequence[], int length, bool expected )
{
if( testName != NULL )
printf( "%s begins: ", testName );

if( VerifySquenceOfBST( sequence, length ) == expected )
printf( "passed.\n" );
else
printf( "failed.\n" );
}

//            10
//         /      \
//        6        14
//       /\        /\
//      4  8     12  16
void Test1()
{
int data[] = { 4, 8, 6, 12, 16, 14, 10 };
Test( "Test1", data, sizeof( data ) / sizeof( int ), true );
}

//           5
//          / \
//         4   7
//            /
//           6
void Test2()
{
int data[] = { 4, 6, 7, 5 };
Test( "Test2", data, sizeof( data ) / sizeof( int ), true );
}

void Test3()
{
int data[] = { 7, 4, 6, 5 };
Test( "Test3", data, sizeof( data ) / sizeof( int ), true );
}

void Test4()
{
Test( "Test4", NULL, 0, false );
}

int main()
{
Test1();
Test2();
Test3();
Test4();

return 0;
}




二十五、二叉树中和为某一值的路径

输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根

结点开始往下一直到叶结点所经过的结点形成一条路径。

#include <iostream>
#include <stdio.h>
#include <vector>

struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};

BinaryTreeNode* CreateBinaryTreeNode( int value )
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = NULL;
pNode->m_pRight = NULL;

return pNode;
}

void ConnectTreeNodes( BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight )
{
if( pParent != NULL )
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
}
}

void DestroyTree( BinaryTreeNode* pRoot )
{
if( pRoot != NULL )
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;

delete pRoot;
pRoot = NULL;

DestroyTree( pLeft );
DestroyTree( pRight );
}
}

void FindPath( BinaryTreeNode* pRoot, int expectedSum,
std::vector<int>& path, int currentSum )
{
currentSum += pRoot->m_nValue;
path.push_back( pRoot->m_nValue );

// 如果是叶结点,并且路径上结点的和等于输入的值
// 打印出这条路径
bool isLeaf = pRoot->m_pLeft == NULL && pRoot->m_pRight == NULL;
if( currentSum == expectedSum && isLeaf )
{
printf( "A path is found: " );
std::vector<int>::iterator iter = path.begin();
for( ; iter != path.end(); ++iter )
printf( "%d\t", *iter );

printf( "\n" );
}

// 如果不是叶结点,则遍历它的子结点
if( pRoot->m_pLeft != NULL )
FindPath( pRoot->m_pLeft, expectedSum, path, currentSum );
if( pRoot->m_pRight != NULL )
FindPath( pRoot->m_pRight, expectedSum, path, currentSum );

// 在返回到父结点之前,在路径上删除当前结点
path.pop_back();
}

void FindPath( BinaryTreeNode* pRoot, int expectedSum )
{
if( pRoot == NULL )
return;

std::vector<int> path;
int currentSum = 0;
FindPath( pRoot, expectedSum, path, currentSum );
}

void Test( const char* testName, BinaryTreeNode* pRoot, int expectedSum )
{
if( testName != NULL )
printf( "%s begins:\n", testName );

FindPath( pRoot, expectedSum );

printf( "\n" );
}

//            10
//         /      \
//        5        12
//       /\
//      4  7
// 有两条路径上的结点和为22
void Test1()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode( 10 );
BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 );
BinaryTreeNode* pNode12 = CreateBinaryTreeNode( 12 );
BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 );
BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 );

ConnectTreeNodes( pNode10, pNode5, pNode12 );
ConnectTreeNodes( pNode5, pNode4, pNode7 );

printf( "Two paths should be found in Test1.\n" );
Test( "Test1", pNode10, 22 );

DestroyTree( pNode10 );
}

//            10
//         /      \
//        5        12
//       /\
//      4  7
// 有两条路径上的结点和为22
void Test2()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode( 10 );
BinaryTreeNode* pNode5 = CreateBinaryTreeNode( 5 );
BinaryTreeNode* pNode12 = CreateBinaryTreeNode( 12 );
BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 );
BinaryTreeNode* pNode7 = CreateBinaryTreeNode( 7 );

ConnectTreeNodes( pNode10, pNode5, pNode12 );
ConnectTreeNodes( pNode5, pNode4, pNode7 );

printf( "No paths should be found in Test2.\n" );
Test( "Test2", pNode10, 15 );

DestroyTree( pNode10 );
}

// 树中没有结点
void Test3()
{
printf( "No paths should be found in Test3.\n" );
Test( "Test3", NULL, 0 );
}

int main()
{
Test1();
Test2();
Test3();

return 0;
}



二十六、复杂链表的复制

请实现函数ComplexListNode* Clone( complexListNode* pHead ),复制一个复杂链表。在复

杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链

表中的任意结点或者NULL。

#include <iostream>
#include <stdio.h>

struct ComplexListNode
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
};

ComplexListNode* CreateNode( int nValue )
{
ComplexListNode* pNode = new ComplexListNode();

pNode->m_nValue = nValue;
pNode->m_pNext = NULL;
pNode->m_pSibling = NULL;

return pNode;
}

void BuildNodes( ComplexListNode* pNode, ComplexListNode* pNext, ComplexListNode* pSibling )
{
if( pNode != NULL )
{
pNode->m_pNext = pNext;
pNode->m_pSibling = pSibling;
}
}

void PrintList( ComplexListNode* pHead )
{
ComplexListNode* pNode = pHead;
while( pNode != NULL )
{
printf( "The value of this node is: %d.\n", pNode->m_nValue );

if( pNode->m_pSibling != NULL )
printf( "The value of its sibling is: %d.\n", pNode->m_pSibling->m_nValue );
else
printf( "This node does not have a sibling.\n" );

printf( "\n" );

pNode = pNode->m_pNext;
}
}

void CloneNodes( ComplexListNode* pHead )
{
ComplexListNode* pNode = pHead;
while( pNode != NULL )
{
ComplexListNode* pCloned = new ComplexListNode();
pCloned->m_nValue = pNode->m_nValue;
pCloned->m_pNext = pNode->m_pNext;
pCloned->m_pSibling = NULL;

pNode->m_pNext = pCloned;

pNode = pCloned->m_pNext;
}
}

void ConnectSiblingNodes( ComplexListNode* pHead )
{
ComplexListNode* pNode = pHead;
while( pNode != NULL )
{
ComplexListNode* pCloned = pNode->m_pNext;
if( pNode->m_pSibling != NULL )
{
pCloned->m_pSibling = pNode->m_pSibling->m_pNext;
}

pNode = pCloned->m_pNext;
}
}

ComplexListNode* ReconnectNodes( ComplexListNode* pHead )
{
ComplexListNode* pNode = pHead;
ComplexListNode* pClonedHead = NULL;
ComplexListNode* pClonedNode = NULL;

if( pNode != NULL )
{
pClonedHead = pClonedNode = pNode->m_pNext;
pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}

while( pNode != NULL )
{
pClonedNode->m_pNext = pNode->m_pNext;
pClonedNode = pClonedNode->m_pNext;

pNode->m_pNext = pClonedNode->m_pNext;
pNode = pNode->m_pNext;
}

return pClonedHead;
}

ComplexListNode* Clone( ComplexListNode* pHead )
{
CloneNodes( pHead );
ConnectSiblingNodes( pHead );
return ReconnectNodes( pHead );
}

void Test( const char* testName, ComplexListNode* pHead )
{
if( testName != NULL )
printf( "%s begins:\n", testName );

printf( "The original list is:\n" );
PrintList( pHead );

ComplexListNode* pClonedHead = Clone( pHead );

printf( "The cloned list is:\n" );
PrintList( pClonedHead );
}

//          -----------------
//         \|/              |
//  1-------2-------3-------4-------5
//  |       |      /|\             /|\
//  --------+--------               |
//          -------------------------
void Test1()
{
ComplexListNode* pNode1 = CreateNode( 1 );
ComplexListNode* pNode2 = CreateNode( 2 );
ComplexListNode* pNode3 = CreateNode( 3 );
ComplexListNode* pNode4 = CreateNode( 4 );
ComplexListNode* pNode5 = CreateNode( 5 );

BuildNodes( pNode1, pNode2, pNode3 );
BuildNodes( pNode2, pNode3, pNode5 );
BuildNodes( pNode3, pNode4, NULL );
BuildNodes( pNode4, pNode5, pNode2 );

Test( "Test1", pNode1 );
}

// 只有一个结点
void Test2()
{
ComplexListNode* pNode1 = CreateNode( 1 );
BuildNodes( pNode1, NULL, pNode1 );

Test( "Test2", pNode1 );
}

int main()
{
Test1();
Test2();

return 0;
}




二十七、二叉搜索树与双向链表

输入一颗二叉搜索树,将该二叉搜索树转化成一个排序的双向链表。要求不能创建任何新的

结点,只能调整树中结点指针的指向。

#include <iostream>
#include <stdio.h>

struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};

BinaryTreeNode* CreateBinaryTreeNode( int value )
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = NULL;
pNode->m_pRight = NULL;

return pNode;
}

void ConnectTreeNodes( BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight )
{
if( pParent != NULL )
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
}
}

void PrintTreeNode( BinaryTreeNode* pNode )
{
if( pNode != NULL )
{
printf( "value of this node is: %d\n", pNode->m_nValue );

if( pNode->m_pLeft != NULL )
printf( "value of its left child is: %d.\n", pNode->m_pLeft->m_nValue );
else
printf( "left child is null.\n" );

if( pNode->m_pRight != NULL )
printf( "value of its right child is: %d.\n", pNode->m_pRight->m_nValue );
else
printf( "right child is null.\n" );
}
else
{
printf( "this node is null.\n" );
}

printf( "\n" );
}

void PrintTree( BinaryTreeNode* pRoot )
{
PrintTreeNode( pRoot );

if( pRoot != NULL )
{
if( pRoot->m_pLeft != NULL )
PrintTree( pRoot->m_pLeft );

if( pRoot->m_pRight != NULL )
PrintTree( pRoot->m_pRight );
}
}

void DestroyTree( BinaryTreeNode* pRoot )
{
if( pRoot != NULL )
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;

delete pRoot;
pRoot = NULL;

DestroyTree( pLeft );
DestroyTree( pRight );
}
}

void ConvertNode( BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList )
{
if( pNode == NULL )
return;

BinaryTreeNode *pCurrent = pNode;

if( pCurrent->m_pLeft != NULL )
ConvertNode( pCurrent->m_pLeft, pLastNodeInList );

pCurrent->m_pLeft = *pLastNodeInList;
if( *pLastNodeInList != NULL )
( *pLastNodeInList )->m_pRight = pCurrent;

*pLastNodeInList = pCurrent;

if( pCurrent->m_pRight != NULL )
ConvertNode( pCurrent->m_pRight, pLastNodeInList );
}

BinaryTreeNode* Convert( BinaryTreeNode* pRootOfTree )
{
BinaryTreeNode *pLastNodeInList = NULL;
ConvertNode( pRootOfTree, &pLastNodeInList );

// pLastNodeInList指向双向链表的尾结点,需要返回头文件
BinaryTreeNode *pHeadOfList = pLastNodeInList;
while( pHeadOfList != NULL && pHeadOfList->m_pLeft != NULL )
pHeadOfList = pHeadOfList->m_pLeft;

return pHeadOfList;
}

void PrintDoubleLinkedList( BinaryTreeNode* pHeadOfList )
{
BinaryTreeNode* pNode = pHeadOfList;

printf( "The nodes from left to right are:\n" );
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );

if( pNode->m_pRight == NULL )
break;
pNode = pNode->m_pRight;
}

printf( "\nThe nodes from right to left are:\n" );
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );

if( pNode->m_pLeft == NULL )
break;
pNode = pNode->m_pLeft;
}

printf( "\n" );
}

void DestroyList( BinaryTreeNode* pHeadOfList )
{
BinaryTreeNode* pNode = pHeadOfList;
while( pNode != NULL )
{
BinaryTreeNode* pNext = pNode->m_pRight;

delete pNode;
pNode = pNext;
}
}

void Test( const char* testName, BinaryTreeNode* pRootOfTree )
{
if( testName != NULL )
printf( "%s begins:\n", testName );

PrintTree( pRootOfTree );

BinaryTreeNode* pHeadOfList = Convert( pRootOfTree );

PrintDoubleLinkedList( pHeadOfList );
}

//            10
//         /      \
//        6        14
//       /\        /\
//      4  8     12  16
void Test1()
{
BinaryTreeNode* pNode10 = CreateBinaryTreeNode( 10 );
BinaryTreeNode* pNode6 = CreateBinaryTreeNode( 6 );
BinaryTreeNode* pNode14 = CreateBinaryTreeNode( 14 );
BinaryTreeNode* pNode4 = CreateBinaryTreeNode( 4 );
BinaryTreeNode* pNode8 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNode12 = CreateBinaryTreeNode( 12 );
BinaryTreeNode* pNode16 = CreateBinaryTreeNode( 16 );

ConnectTreeNodes( pNode10, pNode6, pNode14 );
ConnectTreeNodes( pNode6, pNode4, pNode8 );
ConnectTreeNodes( pNode14, pNode12, pNode16 );

Test( "Test1", pNode10 );

DestroyList( pNode4 );
}

// 树中只有1个结点
void Test2()
{
BinaryTreeNode* pNode1 = CreateBinaryTreeNode( 1 );
Test( "Test2", pNode1 );

DestroyList( pNode1 );
}

// 树中没有结点
void Test3()
{
Test( "Test3", NULL );
}

int main()
{
Test1();
Test2();
Test3();

return 0;
}




二十八、字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符

串a、b、c所能列出来的所有字符串abc、bac、bca、cab和cba。

#include <iostream>
#include <stdio.h>

void Permutation( char* pStr, char* pBegin )
{
if( *pBegin == '\0' )
{
printf( "%s\n", pStr );
}
else
{
for( char* pCh = pBegin; *pCh != '\0'; ++pCh )
{
char temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;

Permutation( pStr, pBegin + 1 );

temp = *pCh;
*pCh = *pBegin;
*pBegin = temp;
}
}
}

void Permutation( char* pStr )
{
if( pStr == NULL )
return;

Permutation( pStr, pStr );
}

void Test( char* pStr )
{
if( pStr == NULL )
printf( "Test for NULL begins:\n" );
else
printf( "Test for %s begins:\n", pStr );

Permutation( pStr );

printf( "\n" );
}

int main()
{
Test( NULL );

char string1[] = "";
Test( string1 );

char string2[] = "a";
Test( string2 );

char string3[] = "ab";
Test( string3 );

char string4[] = "abc";
Test( string4 );

return 0;
}




二十九、数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度,请找出这个数字。例如输入一个长度为9的数组

{ 1, 2, 3,2, 2, 2, 5, 4, 2 }。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

#include <iostream>
#include <stdio.h>

bool CheckMoreThanHalf( int* numbers, int length, int number )
{
int times = 0;
for( int i = 0; i < length; ++i )
{
if( numbers[ i ] == number )
times++;
}

bool isMoreThanHalf = true;
if( times * 2 <= length )
{
isMoreThanHalf = false;
}

return isMoreThanHalf;
}

int MoreThanHalfNum( int* numbers, int length )
{
if( numbers == NULL || length <= 0 )
return 0;

int result = numbers[ 0 ];
int times = 1;
for( int i = 1; i < length; ++i )
{
if( times == 0 )
{
result = numbers[ i ];
times = 1;
}
else if( numbers[ i ] == result )
times++;
else
times--;
}

if( !CheckMoreThanHalf( numbers, length, result ) )
result = 0;

return result;
}

void Test( const char* testName, int* numbers, int length, int expectedValue, bool expectedFlag )
{
if( testName != NULL )
printf( "%s begins: \n", testName );

int* copy = new int[ length ];
for( int i = 0; i < length; ++i )
copy[ i ] = numbers[ i ];

printf( "Test for solution: " );
int result = MoreThanHalfNum( copy, length );
if( result == expectedValue )
printf("Passed.\n");
else
printf("Failed.\n");

delete[ ] copy;
}

// 存在出现次数超过数组长度一半的数字
void Test1()
{
int numbers[] = { 1, 2, 3, 2, 2, 2, 5, 4, 2 };
Test( "Test1", numbers, sizeof( numbers ) / sizeof( int ), 2, false );
}

// 不存在出现次数超过数组长度一半的数字
void Test2()
{
int numbers[] = { 1, 2, 3, 2, 4, 2, 5, 2, 3 };
Test( "Test2", numbers, sizeof( numbers ) / sizeof( int ), 0, true );
}

// 只有一个元素的数组
void Test3()
{
int numbers[] = { 1 };
Test( "Test3", numbers, 1, 1, false );
}

// 输入空指针
void Test4()
{
Test( "Test4", NULL, 0, 0, true );
}

int main()
{
Test1();
Test2();
Test3();
Test4();

return 0;
}




三十、最小的K个数

输入n个整数,找出其中最小的k个数。找出其中最小的k个数。例如输入4、5、1、6、2、

7、3、8这8个数字,则最小的4个数字是1、2、3、4。

#include <iostream>
#include <set>
#include <vector>
#include <stdio.h>

using namespace std;

typedef multiset<int, greater<int> > intSet;
typedef multiset<int, greater<int> >::iterator setIterator;

void GetLeastNumbers( const vector<int>& data, intSet& leastNumbers, int k )
{
leastNumbers.clear();

if( k < 1 || data.size() < k )
return;

vector<int>::const_iterator iter = data.begin();

for( ; iter != data.end(); ++iter )
{
if( leastNumbers.size() < k )
leastNumbers.insert( *iter );

else
{
setIterator iterGreatest = leastNumbers.begin();

if( *iter < *( leastNumbers.begin() ) )
{
leastNumbers.erase( iterGreatest );
leastNumbers.insert( *iter );
}
}
}
}

void Test( const char* testName, int* data, int n, int* expectedResult, int k )
{
if( testName != NULL )
printf( "%s begins: \n", testName );

vector<int> vectorData;
for( int i = 0; i < n; ++i )
vectorData.push_back( data[ i ] );

if( expectedResult == NULL )
printf( "The input is invalid, we don't expect any result.\n" );
else
{
printf( "Expected result: \n" );
for( int i = 0; i < k; ++i )
printf( "%d\t", expectedResult[ i ] );
printf( "\n" );
}

printf( "Result for solution:\n" );
intSet leastNumbers;
GetLeastNumbers( vectorData, leastNumbers, k );
printf( "The actual output numbers are:\n" );
for( setIterator iter = leastNumbers.begin(); iter != leastNumbers.end(); ++iter )
printf( "%d\t", *iter );
printf( "\n\n" );
}

// k小于数组的长度
void Test1()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 3, 8 };
int expected[ ] = { 1, 2, 3, 4} ;
Test( "Test1", data, sizeof( data ) / sizeof( int ), expected, sizeof( expected ) / sizeof( int ) );
}

// k等于数组的长度
void Test2()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 3, 8 };
int expected[ ] = { 1, 2, 3, 4, 5, 6, 7, 8 };
Test( "Test2", data, sizeof( data ) / sizeof( int ), expected, sizeof( expected ) / sizeof( int ) );
}

// k大于数组的长度
void Test3()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 3, 8 };
int* expected = NULL;
Test( "Test3", data, sizeof( data ) / sizeof( int ), expected, 10 );
}

// k等于1
void Test4()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 3, 8 };
int expected[ ] = { 1 };
Test( "Test4", data, sizeof( data ) / sizeof( int ), expected, sizeof( expected ) / sizeof( int ) );
}

// k等于0
void Test5()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 3, 8 };
int* expected = NULL;
Test( "Test5", data, sizeof( data ) / sizeof( int ), expected, 0 );
}

// 数组中有相同的数字
void Test6()
{
int data[ ] = { 4, 5, 1, 6, 2, 7, 2, 8 };
int expected[ ] = { 1, 2 };
Test( "Test6", data, sizeof( data ) / sizeof( int ), expected, sizeof( expected ) / sizeof( int ) );
}

// 输入空指针
void Test7()
{
int* expected = NULL;
Test( "Test7", NULL, NULL, expected, 0 );
}

int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();

return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: