/* 第11题 ------------------------------------ 求二叉树中节点的最大距离... 如果我们把二叉树看成一个图, 父子节点之间的连线看成是双向的, 我们姑且定义"距离"为两节点之间边的个数。 写一个程序, 求一棵二叉树中相距最远的两个节点之间的距离。 */ //July 2010/10/19 //此题思路,tree_star and i 在257、258楼,讲的很明白了。 //定义 一个 结构体 struct NODE { NODE* pLeft; NODE* pRight; int MaxLen; int MaxRgt; }; NODE* pRoot; //根节点 int MaxLength; void traversal_MaxLen(NODE* pRoot) { if(pRoot == NULL) { return 0; }; if(pRoot->pLeft == NULL) { pRoot->MaxLeft = 0; } else //若左子树不为空 { int TempLen = 0; if(pRoot->pLeft->MaxLeft > pRoot->pLeft->MaxRight) //左子树上的,某一节点,往左边大,还是往右边大 { TempLen+=pRoot->pLeft->MaxLeft; } else { TempLen+=pRoot->pLeft->MaxRight; } pRoot->nMaxLeft = TempLen + 1; traversal_MaxLen(NODE* pRoot->pLeft); //此处,加上递归 } if(pRoot->pRigth == NULL) { pRoot->MaxRight = 0; } else //若右子树不为空 { int TempLen = 0; if(pRoot->pRight->MaxLeft > pRoot->pRight->MaxRight) //右子树上的,某一节点,往左边大,还是往右边大 { TempLen+=pRoot->pRight->MaxLeft; } else { TempLen+=pRoot->pRight->MaxRight; } pRoot->MaxRight = TempLen + 1; traversal_MaxLen(NODE* pRoot->pRight); //此处,加上递归 } if(pRoot->MaxLeft + pRoot->MaxRight > 0) { MaxLength=MaxLeft + MaxRight; } }
/* 第12题 题目:求1+2+…+n, 要求不能使用乘除法、for、while、if、else、switch、case等关键字 以及条件判断语句(A?B:C)。 */ //July、2010/10/19 /*----------------- 循环只是让相同的代码执行n遍而已,我们完全可以不用for和while达到这个效果。 比如定义一个类,我们new一含有n个这种类型元素的数组, 那么该类的构造函数将确定会被调用n次。我们可以将需要执行的代码放到构造函数里。 ------------------*/ #include <iostream.h> class Temp { public: Temp() { ++N; Sum += N; } static void Reset() { N = 0; Sum = 0; } static int GetSum() { return Sum; } private: static int N; static int Sum; }; int Temp::N = 0; int Temp::Sum = 0; int solution1_Sum(int n) { Temp::Reset(); Temp *a = new Temp[n]; //就是这个意思,new出n个数组。 delete []a; a = 0; return Temp::GetSum(); } int main() { cout<<solution1_Sum(100)<<endl; return 0; } //运行结果: //5050 //Press any key to continue
/* 第13题: 题目: 输入一个单向链表,输出该链表中倒数第k个结点, 链表的倒数第0个结点为链表的尾指针。 */ //此题一出,相信,稍微有点 经验的同志,都会说到: /*------------------------ 设置两个指针p1,p2 首先p1和p2都指向head 然后p2向前走n步,这样p1和p2之间就间隔k个节点 然后p1和p2同时向前步进,当p2到达最后一个节点时,p1就是倒数第k个节点了 -------------------------*/ //July、2010/10/19 //好了,请你指出 下述代码的错误?: #include <iostream.h> #include <stdio.h> #include <stdlib.h> struct ListNode { char data; ListNode* next; }; ListNode* head,*p,*q; ListNode *pone,*ptwo; int fun(ListNode *head,int k) { pone = ptwo = head; for(int i=0;i<=k;i++) ptwo=ptwo->next; while(ptwo!=NULL) { pone=pone->next; ptwo=ptwo->next; } return pone->data; } int main() { char c; head = (ListNode*)malloc(sizeof(ListNode)); head->next = NULL; p = head; c = getchar(); while(c !='0') { q = (ListNode*)malloc(sizeof(ListNode)); q->data = c; q->next = NULL; p->next = q; p = p->next; c = getchar(); } cout<<"---------------"<<endl; cout<<fun(head,2)<<endl; return 0; }
/* 第14题: 题目:输入一个已经按升序排序过的数组和一个数字, 在数组中查找两个数,使得它们的和正好是输入的那个数字。 要求时间复杂度是O(n)。 如果有多对数字的和等于输入的数字,输出任意一对即可。 例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。 */ //由于数组已经过升序排列,所以,难度下降了不少。 //July、2010/10/19 #include <iostream.h> bool FindTwoNumbersWithSum ( int data[], // 已经排序的 数组 unsigned int length, // 数组长度 int sum, //用户输入的 sum int& num1, // 输出符合和等于sum的第一个数 int& num2 // 第二个数 ) { bool found = false; if(length < 1) return found; int begin = 0; int end = length - 1; while(end > begin) { long curSum = data[begin] + data[end]; if(curSum == sum) { num1 = data[begin]; num2 = data[end]; found = true; break; } else if(curSum > sum) end--; else begin++; } return found; } int main() { int x,y; int a[6]={1,2,4,7,11,15}; if(FindTwoNumbersWithSum(a,6,15,x,y) ) { cout<<x<<endl<<y<<endl; } return 0; } /*----------------- 4 11 Press any key to continue -----------------*/ //扩展:如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变, //如何在O(n)时间里找到这两个数字?
/* 第15题: 题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点。 用递归和循环两种方法完成树的镜像转换。 例如输入: 8 / \ 6 10 / \ / \ 5 7 9 11 输出: 8 / \ 10 6 / \ / \ 11 9 7 5 定义二元查找树的结点为: struct BSTreeNode // a node in the binary search tree (BST) { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node }; */ //就是递归 翻转树,有子树则递归翻转子树。 //July、2010/10/19 void Revertsetree(list *root) { if(!root) return; list *p; p=root->leftch; root->leftch=root->rightch; root->rightch=p; if(root->leftch) Revertsetree(root->leftch); if(root->rightch) Revertsetree(root->rightch); }