编程题——11~20

十一、数值的整数次方

   实现函数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;
}

转载于:https://my.oschina.net/u/2537915/blog/715415

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值