定義棧的數據結構,請在該類型中實現一個可以獲得棧的最小元素的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; }