十一、数值的整数次方
实现函数double Power( double base, int exponent ),求base的exponent。不使用哭函数,同时
不需要考虑大数问题。
/*
实现函数double Power( double base, int exponent ),求base的exponent。不使用哭函数,
同时不需要考虑大数问题。
*/
#include <iostream>
#include <exception>
int exception_num = 1;
double PowerWithUnsignedExponent( double base, unsigned int exponent )
{
double result = 1.0;
for( int i = 1; i <= exponent; i++ )
result *= base;
return result;
}
bool equal( double num1, double num2 )
{
if( ( num1 - num2 > -0.000000001 ) && ( num1 - num2 < 0.000000001 ) )
return true;
else
return false;
}
double Power( double base, int exponent )
{
if( equal( base, 0.0 ) && exponent < 0 )
throw exception_num;
unsigned int absExponent = ( unsigned int )( exponent );
if( exponent < 0 )
absExponent = ( unsigned int )( -exponent );
double result = PowerWithUnsignedExponent( base, absExponent );
if( exponent < 0 )
result = 1.0 / result;
return result;
}
// 正常测试
void Test1()
{
std::cout << " Test1 begins: " << std::endl;
double base = 3.2;
int exponent = 7;
std::cout << " Power( base, exponent ) = " << Power( base, exponent ) << std::endl;
}
// 指数为负数测试
void Test2()
{
std::cout << " Test2 begins: " << std::endl;
double base = 3.2;
int exponent = -7;
std::cout << " Power( base, exponent ) = " << Power( base, exponent ) << std::endl;
}
// 指数为零且基数不为0测试
void Test3()
{
std::cout << " Test3 begins: " << std::endl;
double base = 3.2;
int exponent = 0;
std::cout << " Power( base, exponent ) = " << Power( base, exponent ) << std::endl;
}
// 指数为负且基数为0测试
void Test4()
{
std::cout << " Test4 begins: " << std::endl;
double base = 0;
int exponent = -7;
std::cout << " Power( base, exponent ) = " << Power( base, exponent ) << std::endl;
}
int main()
{
try
{
Test1();
Test2();
Test3();
Test4();
}
catch( int exception_num )
{
std::cout << " error! base is 0." << std::endl;
}
return 0;
}
十二、打印1到最大的n位数
输入数字n,按顺序打印出最大的n位十进制数,比如输入3,则打印出1,2,3一直到最大的3位
数即999.
#include <iostream>
#include <string.h>
#include <stdio.h>
void PrintNumber( char* number )
{
bool isBeginning0 = true;
int nLength = strlen( number );
for( int i = 0; i < nLength; ++i )
{
if( isBeginning0 && number[ i ] != '0' )
isBeginning0 = false;
if( !isBeginning0 )
{
printf( "%c", number[ i ] );
}
}
printf( "\t" );
}
bool Increment( char* number )
{
bool isOverflow = false;
int nTakeOver = 0;
int nLength = strlen( number );
for( int i = nLength - 1; i >= 0; i-- )
{
int nSum = number[ i ] - '0' + nTakeOver;
if( i == nLength - 1 )
nSum++;
if( nSum >= 10 )
{
if( i == 0 )
isOverflow = true;
else
{
nSum -= 10;
nTakeOver = 1;
number[ i ] = '0' + nSum;
}
}
else
{
number[ i ] = '0' + nSum;
break;
}
}
return isOverflow;
}
void PrintToMaxOfNDigits( int n )
{
if( n <= 0 )
return;
char* number = new char[ n + 1 ];
memset( number, '0', n );
number[ n ] = '\0';
while( !Increment( number ) )
{
PrintNumber( number );
}
delete [] number;
}
void Test( int n )
{
printf("Test for %d begins:\n\n", n);
PrintToMaxOfNDigits( n );
printf( "\n\n" );
printf("Test for %d ends.\n\n", n);
}
int main()
{
Test(1);
Test(2);
Test(3);
Test(0);
Test(-1);
return 0;
}
十三、在O(1)时间删除链表结点
给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该节点。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
ListNode* CreateListNode( int value )
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes( ListNode* pCurrent, ListNode* pNext )
{
if( pCurrent == NULL )
{
printf( "Error to connect two nodes.\n" );
exit( 1 );
}
pCurrent->m_pNext = pNext;
}
void PrintListNode( ListNode* pNode )
{
if( pNode == NULL )
{
printf( "\nThe node is NULL\n" );
}
else
{
printf( "\nThe key in node is %d.\n", pNode->m_nValue );
}
}
void PrintList( ListNode* pHead )
{
printf( "\nPrintList start: \n" );
ListNode* pNode = pHead;
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );
pNode = pNode->m_pNext;
}
}
void DestroyList( ListNode* pHead )
{
ListNode* pNode = pHead;
while( pNode != NULL )
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
void DeleteNode( ListNode** pListHead, ListNode* pToBeDeleted )
{
if( !pListHead || !pToBeDeleted )
return;
if( pToBeDeleted->m_pNext != NULL )
{
ListNode* pNext = pToBeDeleted->m_pNext;
pToBeDeleted->m_nValue = pNext->m_nValue;
pToBeDeleted->m_pNext = pNext->m_pNext;
delete pNext;
pNext = NULL;
}
else if( *pListHead == pToBeDeleted )
{
delete pToBeDeleted;
pToBeDeleted = NULL;
*pListHead = NULL;
}
else
{
ListNode* pNode = *pListHead;
while( pNode->m_pNext != pToBeDeleted )
{
pNode = pNode->m_pNext;
}
pNode->m_pNext = NULL;
delete pToBeDeleted;
pToBeDeleted = NULL;
}
}
void Test( ListNode* pListHead, ListNode* pNode )
{
printf( "\nThe original list is: \n" );
PrintList( pListHead );
printf( "\nThe node to be deleted is: \n" );
PrintListNode( pNode );
DeleteNode( &pListHead, pNode );
printf( "\nThe result list is: \n" );
PrintList( pListHead );
}
// 链表中有多个结点,删除中间的结点
void Test1()
{
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
Test( pNode1, pNode3 );
DestroyList(pNode1);
}
// 链表中有多个结点,删除尾结点
void Test2()
{
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
Test( pNode1, pNode5 );
DestroyList( pNode1 );
}
// 链表中有多个结点,删除头结点
void Test3()
{
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
Test( pNode1, pNode1 );
DestroyList( pNode1 );
}
// 链表中有多个结点,删除头结点
void Test4()
{
ListNode* pNode1 = CreateListNode( 1 );
Test( pNode1, pNode1 );
}
// 链表为空
void Test5()
{
Test( NULL, NULL );
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
十四、调整数组顺序使奇数位于偶数前面
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前
半部分,所以偶数位于数组的后半部分。
#include <iostream>
#include <stdio.h>
#include <exception>
int exception_num = 1;
void ReorerOddEven( int* pData, unsigned int length )
{
if( pData == NULL || length <= 0 )
throw exception_num;
int *pBegin = pData;
int *pEnd = pData + length - 1;
while( pBegin < pEnd )
{
while( pBegin < pEnd && ( *pBegin & 0x1 ) != 0 )
pBegin++;
while( pBegin < pEnd && ( *pEnd & 0x1 ) == 0 )
pEnd--;
if( pBegin < pEnd )
{
int temp = *pBegin;
*pBegin = *pEnd;
*pEnd = temp;
}
}
}
void Test1()
{
int data[] = { 1, 2, 3, 4, 5, 6, 7 };
unsigned int length = sizeof( data ) / sizeof( int );
printf("The original array is: \n");
for( int i = 0; i < length; i++ )
printf( "%d\t", data[ i ] );
printf( "\n" );
ReorerOddEven( data, length );
printf("The reordered array is: \n");
for( int i = 0; i < length; i++ )
printf( "%d\t", data[ i ] );
printf( "\n" );
}
int main()
{
try
{
Test1();
}
catch( ... )
{
printf( "invaild input.\n" );
}
return 0;
}
十五、链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计
数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次
是1、2、3、4、5、6.这个链表的倒数第3个结点是值为4的结点。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <stack>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
ListNode* CreateListNode( int value )
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes( ListNode* pCurrent, ListNode* pNext )
{
if( pCurrent == NULL )
{
printf( "Error to connect two nodes.\n" );
exit( 1 );
}
pCurrent->m_pNext = pNext;
}
void PrintListNode( ListNode* pNode )
{
if( pNode == NULL )
{
printf( "\nThe node is NULL\n" );
}
else
{
printf( "\nThe key in node is %d.\n", pNode->m_nValue );
}
}
void PrintList( ListNode* pHead )
{
printf( "PrintList start: \n" );
ListNode* pNode = pHead;
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );
pNode = pNode->m_pNext;
}
}
void DestroyList( ListNode* pHead )
{
ListNode* pNode = pHead;
while( pNode != NULL )
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
ListNode* FindKthToTail( ListNode* pListHead, unsigned int k )
{
if( pListHead == NULL || k == 0 )
{
return NULL;
}
ListNode *pAhead = pListHead;
ListNode *pBehind = NULL;
for( unsigned int i = 0; i < k - 1; ++i )
{
if( pAhead->m_pNext != NULL )
pAhead = pAhead->m_pNext;
else
{
return NULL;
}
}
pBehind = pListHead;
while( pAhead->m_pNext != NULL )
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
// 测试要找的结点在链表中间
void Test1()
{
printf( "=====Test1 starts:=====\n" );
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pNode = FindKthToTail( pNode1, 2 );
PrintListNode( pNode );
DestroyList( pNode1 );
}
// 测试要找的结点是链表的尾结点
void Test2()
{
printf( "=====Test2 starts:=====\n" );
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pNode = FindKthToTail( pNode1, 1 );
PrintListNode( pNode );
DestroyList( pNode1 );
}
// 测试要找的结点是链表的头结点
void Test3()
{
printf( "=====Test3 starts:=====\n" );
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pNode = FindKthToTail( pNode1, 5 );
PrintListNode( pNode );
DestroyList( pNode1 );
}
// 测试输入的第二个参数大于链表的结点总数
void Test4()
{
printf( "=====Test4 starts:=====\n" );
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pNode = FindKthToTail( pNode1, 6 );
PrintListNode( pNode );
DestroyList( pNode1 );
}
// 测试输入的第二个参数为0
void Test5()
{
printf( "=====Test5 starts:=====\n" );
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pNode = FindKthToTail( pNode1, 0 );
PrintListNode( pNode );
DestroyList( pNode1 );
}
int main()
{
Test1();
Test2();
Test3();
Test4();
Test5();
return 0;
}
十六、反转链表
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
ListNode* CreateListNode( int value )
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes( ListNode* pCurrent, ListNode* pNext )
{
if( pCurrent == NULL )
{
printf( "Error to connect two nodes.\n" );
exit( 1 );
}
pCurrent->m_pNext = pNext;
}
void PrintListNode( ListNode* pNode )
{
if( pNode == NULL )
{
printf( "The node is NULL\n" );
}
else
{
printf( "The key in node is %d.\n", pNode->m_nValue );
}
}
void PrintList( ListNode* pHead )
{
printf( "PrintList start: \n" );
ListNode* pNode = pHead;
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );
pNode = pNode->m_pNext;
}
}
void DestroyList( ListNode* pHead )
{
ListNode* pNode = pHead;
while( pNode != NULL )
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
ListNode* ReverseList( ListNode* pHead )
{
ListNode* pReversedHead = NULL;
ListNode* pNode = pHead;
ListNode* pPrev = NULL;
while( pNode != NULL )
{
ListNode* pNext = pNode->m_pNext;
if( pNext == NULL )
pReversedHead = pNode;
pNode->m_pNext = pPrev;
pPrev = pNode;
pNode = pNext;
}
return pReversedHead;
}
ListNode* Test( ListNode* pHead )
{
printf("\nThe original list is: \n");
PrintList( pHead );
ListNode* pReversedHead = ReverseList( pHead );
printf("\nThe reversed list is: \n");
PrintList( pReversedHead );
return pReversedHead;
}
// 输入的链表有多个结点
void Test1()
{
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pNode2 = CreateListNode( 2 );
ListNode* pNode3 = CreateListNode( 3 );
ListNode* pNode4 = CreateListNode( 4 );
ListNode* pNode5 = CreateListNode( 5 );
ConnectListNodes( pNode1, pNode2 );
ConnectListNodes( pNode2, pNode3 );
ConnectListNodes( pNode3, pNode4 );
ConnectListNodes( pNode4, pNode5 );
ListNode* pReversedHead = Test( pNode1 );
DestroyList( pReversedHead );
}
// 输入的链表只有一个结点
void Test2()
{
ListNode* pNode1 = CreateListNode( 1 );
ListNode* pReversedHead = Test( pNode1 );
DestroyList( pReversedHead );
}
// 输入空链表
void Test3()
{
Test( NULL );
}
int main()
{
Test1();
Test2();
Test3();
return 0;
}
十七、合并两个排序的链表
输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然按照递增排序的。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
ListNode* CreateListNode( int value )
{
ListNode* pNode = new ListNode();
pNode->m_nValue = value;
pNode->m_pNext = NULL;
return pNode;
}
void ConnectListNodes( ListNode* pCurrent, ListNode* pNext )
{
if( pCurrent == NULL )
{
printf( "Error to connect two nodes.\n" );
exit( 1 );
}
pCurrent->m_pNext = pNext;
}
void PrintListNode( ListNode* pNode )
{
if( pNode == NULL )
{
printf( "The node is NULL\n" );
}
else
{
printf( "The key in node is %d.\n", pNode->m_nValue );
}
}
void PrintList( ListNode* pHead )
{
printf( "PrintList start: \n" );
ListNode* pNode = pHead;
while( pNode != NULL )
{
printf( "%d\t", pNode->m_nValue );
pNode = pNode->m_pNext;
}
}
void DestroyList( ListNode* pHead )
{
ListNode* pNode = pHead;
while( pNode != NULL )
{
pHead = pHead->m_pNext;
delete pNode;
pNode = pHead;
}
}
ListNode* Merge( ListNode* pHead1, ListNode* pHead2 )
{
if( pHead1 == NULL )
return pHead2;
else if( pHead2 == NULL )
return pHead1;
ListNode* pMergedHead = NULL;
if( pHead1->m_nValue < pHead2->m_nValue )
{
pMergedHead = pHead1;
pMergedHead->m_pNext = Merge( pHead1->m_pNext, pHead2 );
}
else
{
pMergedHead = pHead2;
pMergedHead->m_pNext = Merge( pHead1, pHead2->m_pNext );
}
return pMergedHead;
}
ListNode* Test( const char* testName, ListNode* pHead1, ListNode* pHead2 )
{
if( testName != NULL )
printf( "%s begins:\n", testName );
printf( "\nThe first list is:\n" );
PrintList( pHead1 );
printf( "\nThe second list is:\n" );
PrintList( pHead2 );
printf( "\nThe merged list is:\n" );
ListNode* pMergedHead = Merge( pHead1, pHead2 );
PrintList( pMergedHead );
printf("\n\n");
return pMergedHead;
}
// list1: 1->3->5
// list2: 2->4->6
void Test1()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode3);
ConnectListNodes(pNode3, pNode5);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode6 = CreateListNode(6);
ConnectListNodes(pNode2, pNode4);
ConnectListNodes(pNode4, pNode6);
ListNode* pMergedHead = Test("Test1", pNode1, pNode2);
DestroyList( pMergedHead );
}
// 链表里有重复数字
// list1: 1->3->5
// list2: 2->3->6
void Test2()
{
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode3);
ConnectListNodes(pNode3, pNode5);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode4 = CreateListNode(3);
ListNode* pNode6 = CreateListNode(6);
ConnectListNodes(pNode2, pNode4);
ConnectListNodes(pNode4, pNode6);
ListNode* pMergedHead = Test("Test2", pNode1, pNode2);
DestroyList( pMergedHead );
}
// 两个链表都为空链表
// list1: 空链表
// list2: 空链表
void Test3()
{
ListNode* pMergedHead = Test( "Test3", NULL, NULL );
}
int main()
{
Test1();
Test2();
Test3();
return 0;
}
十八、树的子结构
输入两棵树A和B,判断B是不是A的子结构。
#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 DestroyTree( BinaryTreeNode* pRoot )
{
if(pRoot != NULL)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;
delete pRoot;
pRoot = NULL;
DestroyTree( pLeft );
DestroyTree( pRight );
}
}
bool DoesTree1HaveTree2( BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2 )
{
if( pRoot2 == NULL )
return true;
if( pRoot1 == NULL )
return false;
if( pRoot1->m_nValue != pRoot2->m_nValue )
return false;
return DoesTree1HaveTree2( pRoot1->m_pLeft, pRoot2->m_pLeft ) &&
DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);
}
bool HasSubtree( BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2 )
{
bool result = false;
if( pRoot1 != NULL && pRoot2 != NULL )
{
if( pRoot1->m_nValue == pRoot2->m_nValue )
result = DoesTree1HaveTree2( pRoot1, pRoot2 );
if( !result )
result = HasSubtree( pRoot1->m_pLeft, pRoot2 );
if( !result )
result = HasSubtree( pRoot1->m_pRight, pRoot2 );
}
return result;
}
void Test( const char* testName, BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2, bool expected )
{
if( HasSubtree( pRoot1, pRoot2 ) == expected )
printf( "%s passed.\n", testName );
else
printf( "%s failed.\n", testName );
}
// 树中结点含有分叉,树B是树A的子结构
// 8 8
// / \ / \
// 8 7 9 2
// / \
// 9 2
// / \
// 4 7
void Test1()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode( 7 );
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode( 9 );
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode( 2 );
BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode( 4 );
BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode( 7 );
ConnectTreeNodes( pNodeA1, pNodeA2, pNodeA3 );
ConnectTreeNodes( pNodeA2, pNodeA4, pNodeA5 );
ConnectTreeNodes( pNodeA5, pNodeA6, pNodeA7 );
BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode( 9 );
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode( 2 );
ConnectTreeNodes( pNodeB1, pNodeB2, pNodeB3 );
Test("Test1", pNodeA1, pNodeB1, true);
DestroyTree( pNodeA1 );
DestroyTree( pNodeB1 );
}
// 树中结点含有分叉,树B不是树A的子结构
// 8 8
// / \ / \
// 8 7 9 2
// / \
// 9 3
// / \
// 4 7
void Test2()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode( 7 );
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode( 9 );
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode( 3 );
BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode( 4 );
BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode( 7 );
ConnectTreeNodes( pNodeA1, pNodeA2, pNodeA3 );
ConnectTreeNodes( pNodeA2, pNodeA4, pNodeA5 );
ConnectTreeNodes( pNodeA5, pNodeA6, pNodeA7 );
BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode( 8 );
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode( 9 );
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode( 2 );
ConnectTreeNodes( pNodeB1, pNodeB2, pNodeB3 );
Test( "Test2", pNodeA1, pNodeB1, false );
DestroyTree( pNodeA1 );
DestroyTree( pNodeB1 );
}
// 树A和树B都为空
void Test3()
{
Test( "Test3", NULL, NULL, false );
}
int main()
{
Test1();
Test2();
Test3();
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 MirrorRecursively( BinaryTreeNode* pNode )
{
if( pNode == NULL )
return;
if( pNode->m_pLeft == NULL && pNode->m_pRight == NULL )
return;
BinaryTreeNode *pTemp = pNode->m_pLeft;
pNode->m_pLeft = pNode->m_pRight;
pNode->m_pRight = pTemp;
if( pNode->m_pLeft )
MirrorRecursively( pNode->m_pLeft );
if( pNode->m_pRight )
MirrorRecursively( 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: MirrorRecursively=====\n" );
MirrorRecursively( pNode8 );
PrintTree( pNode8 );
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: MirrorRecursively=====\n" );
MirrorRecursively( pNode8 );
PrintTree( pNode8 );
DestroyTree( pNode8 );
}
int main()
{
Test1();
Test2();
return 0;
}
二十、顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印打印出每个数字。
#include <iostream>
#include <stdio.h>
void printNumber( int number )
{
printf( "%d\t", number );
}
void PrintMatrixInCircle( int** data, int columns, int rows, int start )
{
int endX = columns - 1 - start;
int endY = rows - 1 - start;
// 从左到右打印一行
for( int i = start; i <= endX; ++i )
{
int number = data[ start ][ i ];
printNumber( number );
}
// 从上到下打印一列
if( start < endY )
{
for( int i = start + 1; i <= endY; ++i )
{
int number = data[ i ][ endX ];
printNumber( number );
}
}
// 从右到左打印一行
if( start < endX && start < endY )
{
for( int i = endX - 1; i >= start; --i )
{
int number = data[ endY ][ i ];
printNumber( number );
}
}
// 从下到上打印一列
if( start < endX && start < endY - 1 )
{
for( int i = endY - 1; i >= start + 1; --i )
{
int number = data[ i ][ start ];
printNumber( number );
}
}
}
void PrintMatrixClockwisely( int** data, int columns, int rows )
{
if( data == NULL || columns <= 0 || rows <= 0 )
return;
int start = 0;
while( columns > start * 2 && rows > start * 2 )
{
PrintMatrixInCircle( data, columns, rows, start );
++start;
}
}
void Test( int columns, int rows )
{
printf( "Test Begin: %d columns, %d rows.\n", columns, rows );
if( columns < 1 || rows < 1 )
return;
int** numbers = new int*[ rows ];
for( int i = 0; i < rows; ++i )
{
numbers[ i ] = new int[ columns ];
for( int j = 0; j < columns; ++j )
{
numbers[ i ][ j ] = i * columns + j + 1;
}
}
PrintMatrixClockwisely( numbers, columns, rows );
printf( "\n" );
for( int i = 0; i < rows; ++i )
delete[ ] ( int* )numbers[ i ];
delete[ ] numbers;
}
int main()
{
Test(2, 2);
Test(4, 4);
return 0;
}