定义栈的数据结构,请在该类型中实现一个可以获得栈的最小元素的min函数。在该栈中,调node
用min、push及pop的时间复杂度都是O(1)。ios
/* 定义栈的数据结构,请在该类型中实现一个可以获得栈的最小元素的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 ); }
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺数组
序。假设压入栈假设压入栈的全部数字均不相等。例如序列一、二、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 ) { 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; }
从上往下打印出二叉树的每一个结点,同一层的结点按照从左到右的顺序打印。ui
#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; }
输入一个整数数组,判断该数组是否是某二叉搜索树的后序遍历的结果。若是是则返回this
true,不然返回false。假设输入的数组的任何两个数字都互不相同。spa
#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、数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度,请找出这个数字。例如输入一个长度为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; }
三10、最小的K个数
输入n个整数,找出其中最小的k个数。找出其中最小的k个数。例如输入四、五、一、六、二、
七、三、8这8个数字,则最小的4个数字是一、二、三、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; }