剑指offer——解决问题的思路(第四章)
面试题19:二叉树的镜像
请完成一个函数,输入一棵二叉树,该函数输出它的镜像
思路:
依旧是递归:确定递归结束的条件、递归体以及部分细节即可
递归结束:结点的左右子树均为空
递归体:交换结点的左右子树
1 #include <iostream> 2 using namespace std; 3 struct Node 4 { 5 int m_nValue; 6 Node* m_pLeft; 7 Node* m_pRight; 8 }; 9 void CreateTree(Node*& t); 10 void MakeTree(Node*& t,int x,Node* r1,Node* r2); 11 void Print(Node* t); 12 void Mirror(Node* t); 13 int main() 14 { 15 Node* t5,*t6,*t7,*t8,*t9,*t10,*t11,*x,*y; 16 t5=t6=t7=t8=t9=t10=t11=x=y=NULL; 17 MakeTree(t5,5,x,y); MakeTree(t7,7,x,y); MakeTree(t9,9,x,y); MakeTree(t11,11,x,y); 18 MakeTree(t6,6,t5,t7); MakeTree(t10,10,t9,t11); 19 MakeTree(t8,8,t6,t10); 20 Print(t8); 21 cout<<endl; 22 Mirror(t8); 23 Print(t8); 24 return 0; 25 } 26 void MakeTree(Node*& t,int x,Node* r1,Node* r2) 27 { 28 t=new Node(); 29 t->m_nValue=x; 30 t->m_pLeft=r1; 31 t->m_pRight=r2; 32 r1=r2=NULL; 33 } 34 void CreateTree(Node*& t) 35 { 36 int val; 37 cin>>val; 38 if(val==0) 39 t=NULL; 40 else 41 { 42 t=new Node(); 43 t->m_nValue=val; 44 t->m_pLeft=NULL; 45 t->m_pRight=NULL; 46 CreateTree(t->m_pLeft); 47 CreateTree(t->m_pRight); 48 } 49 } 50 void Print(Node* t) 51 { 52 if(t==NULL) 53 return; 54 cout<<t->m_nValue<<" "; 55 Print(t->m_pLeft); 56 Print(t->m_pRight); 57 } 58 void Mirror(Node* t) 59 { 60 if(!t) return; 61 if(!t->m_pLeft&&!t->m_pRight) 62 return; 63 Node* temp=t->m_pLeft; 64 t->m_pLeft=t->m_pRight; 65 t->m_pRight=temp; 66 if(t->m_pLeft) 67 Mirror(t->m_pLeft); 68 if(t->m_pRight) 69 Mirror(t->m_pRight); 70 }
面试题20:顺时针打印矩阵
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:输入以下矩阵
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
则依次输出数字:1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10
思路:
没有复杂的数据结构以及高级算法,需要的是缜密的逻辑分析以及细节(问题比较复杂,最好想清楚再写代码)
复杂问题——分解——
按圈打印,每次开始的位置是相似的:(x,x)到(x+1,x+1)(正常情况下)——(start,start)——(startX,startY)
打印几圈?即循环次数:
rows>(start*2)&&columns>(start*2)
start++;
确定了打印的圈数后,就是打印一圈的函数设计了。打印一圈时,需要注意以下三种特殊情况。
特殊情况:针对最里面的一圈
1 #include <iostream> 2 using namespace std; 3 void Print(int arr[][4],int rows,int columns); 4 void Print_Circle(int arr[][4],int rows,int columns,int stat); 5 int main() 6 { 7 int arr[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; 8 int m=4,n=4; 9 Print(arr,m,n); 10 return 0; 11 } 12 void Print(int arr[][4],int rows,int columns) 13 { 14 if(rows<=0||columns<=0||!arr) return; 15 int start=0; 16 while(rows>2*start&&columns>2*start) 17 { 18 Print_Circle(arr,rows,columns,start); 19 start++; 20 } 21 } 22 void Print_Circle(int arr[][4],int rows,int columns,int start)//已知起始坐标(start,start),关键是对角坐标。 23 { 24 int endX=columns-start-1, endY=rows-start-1; 25 //从左到右:第一行: 26 for(int i=start;i<=endX;i++) 27 cout<<arr[start][i]<<" "; 28 //从上到下:一列(考虑图中第三种特殊情况,只有第一行) 29 if(start<endY)//满足这个条件才打印 30 { 31 for(int i=start+1;i<=endY;i++) 32 cout<<arr[i][endY]<<" "; 33 } 34 //从右至左:第二行(考虑图中第2种特殊情况,只有第一行和第一列) 35 if(start<endX&&start<endY) 36 { 37 for(int i=endX-1;i>=start;i--) 38 cout<<arr[endY][i]<<" "; 39 } 40 //从下到上:最后一列(考虑图中第一种特殊情况,只有两行一列) 41 if(start<endY-1&&start<endX) 42 { 43 for(int i=endY-1;i>=start+1;i--) 44 cout<<arr[i][start]<<" "; 45 } 46 47 }
面试题21:包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数,调用min、push、pop、的时间复杂度都是O(1)。
思路:
第一个想法是使用辅助栈。辅助栈栈顶保存最小元素,并且在能够根据push、pop及时更新辅助栈。
这里的关键是辅助栈如何更新数据:
主栈压入数据后,辅助栈压入:如果该数<辅助栈的栈顶元素,则将该数压入辅助栈,否则,重复压入辅助栈栈顶,这就使得辅助栈的栈顶元素始终为当前主栈中的最小值,并且即使主栈pop,辅助栈中的栈顶依旧为当前主栈的最小元素。
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 class Stack 5 { 6 private: 7 stack<int> s; 8 stack<int> min; 9 public: 10 Stack(){}; 11 ~Stack(){}; 12 void Push(int val); 13 void Pop(); 14 int Min(); 15 }; 16 void Stack::Push(int val) 17 { 18 s.push(val); 19 if(min.empty()||min.top()>=val) 20 min.push(val); 21 else 22 { 23 int temp=min.top(); 24 min.push(temp); 25 } 26 } 27 void Stack::Pop() 28 { 29 if(!s.empty()&&!min.empty()) 30 { 31 s.pop(); 32 min.pop(); 33 } 34 } 35 int Stack::Min() 36 { 37 if(!min.empty()) 38 return min.top(); 39 } 40 int main() 41 { 42 Stack ss; 43 ss.Push(3); 44 cout<<"Min: "<<ss.Min()<<endl; 45 ss.Push(4); 46 cout<<"Min: "<<ss.Min()<<endl; 47 ss.Push(2); 48 cout<<"Min: "<<ss.Min()<<endl; 49 ss.Push(1); 50 cout<<"Min: "<<ss.Min()<<endl; 51 ss.Pop(); 52 cout<<"Min: "<<ss.Min()<<endl; 53 ss.Pop(); 54 cout<<"Min: "<<ss.Min()<<endl; 55 ss.Push(0); 56 cout<<"Min: "<<ss.Min()<<endl; 57 return 0; 58 }
面试题22:栈的压入弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为栈的弹出顺序。假设入栈的所有数字均不相等。例如:序列1、2、3、4、5是某栈的压栈序列,4、5、3、2、1就是该压栈序列的出栈序列,但4、3、5、1、2就不可能是该栈的出栈序列。
思路:
在有关栈的题目中,经常需要使用辅助栈,并结合实例进行过程分析。从正反两方面来进行分析,得到基本思路。
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 bool IsPopOrder(int* arr1,int* arr2,int len); 5 int main() 6 { 7 int arr1[5]={1,2,3,4,5}; 8 int arr2[5]={4,5,3,2,1}; 9 int arr3[5]={4,3,5,1,2}; 10 int len=5; 11 bool f1=IsPopOrder(arr1,arr2,len); 12 bool f2=IsPopOrder(arr1,arr3,len); 13 if(f1) 14 cout<<"arr2 is PopOrder of arr1!"<<endl; 15 else 16 cout<<"arr2 is not PopOrder of arr1!"<<endl; 17 if(f2) 18 cout<<"arr3 is PopOrder of arr1!"<<endl; 19 else 20 cout<<"arr3 is not PopOrder of arr1!"<<endl; 21 return 0; 22 } 23 bool IsPopOrder(int* arr1,int* arr2,int len) 24 { 25 bool flag=false; 26 if(arr1&&arr2&&len>0) 27 { 28 stack<int> s; 29 int i=0,j=0; 30 while(j<len) 31 { 32 if(s.empty()||s.top()!=arr2[j])//这里需要注意或这个关系的顺序。空的栈是不能进行top操作的,会导致运行出错 33 { 34 if(i==len)//如果全部入栈后,栈顶元素与出栈元素依旧不相等,那肯定是不对的 35 break; 36 s.push(arr1[i]); 37 i++; 38 } 39 else 40 { 41 s.pop(); 42 j++; 43 } 44 } 45 if(s.empty()&&j==len) 46 flag=true; 47 } 48 return flag; 49 }
面试题23:从上往下打印二叉树
从上往下打印二叉树的每一个结点,同一层的按从左到右的顺序打印。例如图中的二叉树,则依次打印出8、6、10、5、7、9、11
思路:
这个题目的关键是:使用辅助的数据结构:队列。循环实现。
总根结点进队。
循环体: 在队列中,打印队首结点=根结点(同时出队),然后左右子树结点分别进队~(没有子结点就跳过)
结束条件:队列为空
流程如下:
队列:8——打印8——6、10进队(6,10)——打印6——5、7进队(10,5,7)——打印10——9、11进队(5,7,9,11)
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 struct Node 5 { 6 int m_nValue; 7 Node* m_pLeft; 8 Node* m_pRight; 9 }; 10 void CreateTree(Node*& t); 11 void MakeTree(Node*& t,int x,Node* r1,Node* r2); 12 void Print(Node* t); 13 void PrintLevel(Node* t); 14 int main() 15 { 16 Node* t5,*t6,*t7,*t8,*t9,*t10,*t11,*x,*y; 17 t5=t6=t7=t8=t9=t10=t11=x=y=NULL; 18 MakeTree(t5,5,x,y); MakeTree(t7,7,x,y); MakeTree(t9,9,x,y); MakeTree(t11,11,x,y); 19 MakeTree(t6,6,t5,t7); MakeTree(t10,10,t9,t11); 20 MakeTree(t8,8,t6,t10); 21 // Print(t8); 22 PrintLevel(t8); 23 return 0; 24 } 25 void MakeTree(Node*& t,int x,Node* r1,Node* r2) 26 { 27 t=new Node(); 28 t->m_nValue=x; 29 t->m_pLeft=r1; 30 t->m_pRight=r2; 31 r1=r2=NULL; 32 } 33 void CreateTree(Node*& t) 34 { 35 int val; 36 cin>>val; 37 if(val==0) 38 t=NULL; 39 else 40 { 41 t=new Node(); 42 t->m_nValue=val; 43 t->m_pLeft=NULL; 44 t->m_pRight=NULL; 45 CreateTree(t->m_pLeft); 46 CreateTree(t->m_pRight); 47 } 48 } 49 void Print(Node* t) 50 { 51 if(t==NULL) 52 return; 53 cout<<t->m_nValue<<" "; 54 Print(t->m_pLeft); 55 Print(t->m_pRight); 56 } 57 void PrintLevel(Node* t) 58 { 59 if(!t) return; 60 queue<Node*> q; 61 q.push(t); 62 while(q.size()) 63 { 64 Node* temp=q.front(); 65 cout<<temp->m_nValue<<" "; 66 q.pop(); 67 if(temp->m_pLeft) 68 q.push(temp->m_pLeft); 69 if(temp->m_pRight) 70 q.push(temp->m_pRight); 71 } 72 }
面试题24:二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是否为某二叉树的后序遍历的结果。如果是则返回true,否则返回false;假设输入的数组的任意两个数字都不相同。
例如:输入{5,7,6,9,11,10,8}则返回true,因为它是下图的后序遍历的结果。
输入{7,4,6,5}则返回false,因为没有一棵二叉搜索树的后序遍历结果是它。
思路:
肯定是递归判定了,
(1)二叉搜索树的特点:根结点的值大于所有左子树结点的值,小于所有右子树结点的值
(2)后序遍历的特点:最后一个结点为根结点
因此根据(2),我们很容易得到二叉树的根结点与左右子树。左子树的结点值必然是数组前面小于根结点的值。而右子树的结点值是第一个大于根结点的值以及其后面到根结点前一个的结点的值。因此左子树要么为空,要么就是正确的。从而问题就转为判断右子树:
右子树的判断就不难了,将右子树中的所有值与根结点的值相比较,一旦比根结点的值小,则必然不是二叉搜索树!
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 bool IsPostOrder(int* arr,int len); 5 int main() 6 { 7 int arr1[7]={5,7,6,9,11,10,8}; 8 int arr2[4]={7,4,6,5}; 9 bool f1=IsPostOrder(arr1,7); 10 bool f2=IsPostOrder(arr2,4); 11 if(f1) cout<<"arr1 is."<<endl; 12 else cout<<"arr1 is not."<<endl; 13 if(f2) cout<<"arr2 is."<<endl; 14 else cout<<"arr2 is not."<<endl; 15 return 0; 16 } 17 bool IsPostOrder(int* arr,int len) 18 { 19 if(!arr||len<=0) 20 return false; 21 int root=arr[len-1]; 22 int i; 23 //从头开始遍历数组的话,结点值小于根结点的必然属于左子树 24 for(i=0;i<len-1;i++) 25 { 26 if(arr[i]>root) 27 break; 28 } 29 int j; 30 for(j=i;j<len-1;j++) 31 { 32 if(arr[j]<root)//右子树中不能有比根结点小的值,一旦出现,必然不是二叉搜索树~ 33 return false; 34 } 35 //判断左子树是不是: 36 bool left=true; 37 if(i>0)//使用大于号,因为如果为0,返回的是false,而空树是可以接受的,而默认是true。 38 left=IsPostOrder(arr,i); 39 //判断右子树是不是: 40 bool right=true; 41 if(len-i-1>0) 42 right=IsPostOrder(arr+i,len-i-1); 43 return left&&right; 44 }
面试题25:二叉树中和为某一值的路径
输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。从树的根结点开始往下一直到叶子节点所经过的所有结点形成一条路径。例如:
输入22,路径有:10、5、7;10、12
思路:
使用vector作为存储路径的容器。——按照前序遍历访问每个结点,访问每个结点时:
判断该结点是否为叶子结点&&当前路径和是否满足要求
是的话,打印
否则,继续遍历左右子树结点(递归实现)
最后,回到父节点时,需要弹出当前结点。
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 struct Node 5 { 6 int m_nValue; 7 Node* m_pLeft; 8 Node* m_pRight; 9 }; 10 void CreateTree(Node*& t); 11 void MakeTree(Node*& t,int x,Node* r1,Node* r2); 12 void Print(Node* t); 13 void Path(Node* t,int n); 14 void FindPath(Node* t,int n,vector<Node*> path,int cursum); 15 int main() 16 { 17 Node* t4,*t5,*t7,*t10,*t12,*x,*y; 18 t4=t5=t7=t10=t12=x=y=NULL; 19 MakeTree(t4,4,x,y); MakeTree(t7,7,x,y); 20 MakeTree(t5,5,t4,t7); MakeTree(t12,12,x,y); 21 MakeTree(t10,10,t5,t12); 22 Path(t10,22); 23 return 0; 24 } 25 void MakeTree(Node*& t,int x,Node* r1,Node* r2) 26 { 27 t=new Node(); 28 t->m_nValue=x; 29 t->m_pLeft=r1; 30 t->m_pRight=r2; 31 r1=r2=NULL; 32 } 33 void CreateTree(Node*& t) 34 { 35 int val; 36 cin>>val; 37 if(val==0) 38 t=NULL; 39 else 40 { 41 t=new Node(); 42 t->m_nValue=val; 43 t->m_pLeft=NULL; 44 t->m_pRight=NULL; 45 CreateTree(t->m_pLeft); 46 CreateTree(t->m_pRight); 47 } 48 } 49 void Print(Node* t) 50 { 51 if(t==NULL) 52 return; 53 cout<<t->m_nValue<<" "; 54 Print(t->m_pLeft); 55 Print(t->m_pRight); 56 } 57 void Path(Node* t,int n) 58 { 59 if(!t) return; 60 vector<Node*> path; 61 int cursum=0; 62 FindPath(t,n,path,cursum); 63 } 64 void FindPath(Node* t,int n,vector<Node*> path,int cursum) 65 { 66 cursum+=t->m_nValue; 67 path.push_back(t); 68 bool IsLeaf=((t->m_pLeft==NULL)&&(t->m_pRight==NULL)); 69 if(IsLeaf&&cursum==n) 70 { 71 cout<<"A path is found: "<<endl; 72 vector<Node*>::iterator iter=path.begin(); 73 for(;iter!=path.end();iter++) 74 cout<<(*iter)->m_nValue<<" "; 75 cout<<endl; 76 } 77 if(t->m_pLeft) 78 FindPath(t->m_pLeft,n,path,cursum); 79 if(t->m_pRight) 80 FindPath(t->m_pRight,n,path,cursum); 81 path.pop_back(); 82 }
面试题26:复杂链表的复制
请实现函数ComplexListNode* Clone*(ComplexListNode* pHead),复制一个复杂链表。在复杂链表中,每个结点除了有一个m_pNext指针指向下一个结点外,还有一个m_pSibling指向链表中任意结点或者NULL。
结点定义如下:
struct ComplexListNode*
{
int m_nValue;
ComplexListNode* m_pNext;
ComplexListNode* m_pSibling;
}
思路1:
复制原来链表上的每个结点,并用pNext链接;
设置pSibling
思路2:
空间换时间,新创建的结点在原结点后面,这样pSiblibing容易设置。最后再拆开来
1 #include <iostream> 2 using namespace std; 3 struct ComplexListNode 4 { 5 int m_nValue; 6 ComplexListNode* m_pNext; 7 ComplexListNode* m_pSibling; 8 }; 9 void CreateList(ComplexListNode** head); 10 void SetSibling(ComplexListNode* head); 11 ComplexListNode* Find(ComplexListNode* head,int val);//定位值为val结点,用于设置Sibling、 12 void Print(ComplexListNode* head); 13 ComplexListNode* Clone(ComplexListNode* head); 14 ComplexListNode* Split(ComplexListNode* head);//将复制后的长链表拆分为两个相同的链表,一个为原链表,一个为复制的链表 15 int main() 16 { 17 ComplexListNode* head=NULL; 18 CreateList(&head); 19 ComplexListNode* CloneHead=Clone(head); 20 Print(CloneHead); 21 return 0; 22 } 23 24 void CreateList(ComplexListNode** head) 25 { 26 int val; 27 while(cin>>val) 28 { 29 ComplexListNode* temp=new ComplexListNode(); 30 temp->m_nValue=val; 31 temp->m_pNext=temp->m_pSibling=NULL; 32 if(*head==NULL) 33 *head=temp; 34 else 35 { 36 ComplexListNode* p=*head; 37 while(p->m_pNext) 38 p=p->m_pNext; 39 p->m_pNext=temp; 40 } 41 } 42 SetSibling(*head); 43 } 44 void SetSibling(ComplexListNode* head)//照着书上的例子设计。 45 { 46 if(!head) return; 47 ComplexListNode* p; 48 p=head; 49 p->m_pSibling=Find(head,3); 50 p=p->m_pNext; 51 p->m_pSibling=Find(head,5); 52 p=p->m_pNext; 53 p->m_pSibling=NULL; 54 p=p->m_pNext; 55 p->m_pSibling=Find(head,2); 56 p=p->m_pNext; 57 p->m_pSibling=NULL; 58 } 59 ComplexListNode* Find(ComplexListNode* head,int val) 60 { 61 if(!head) return NULL; 62 ComplexListNode* p=head; 63 while(p) 64 { 65 if(p->m_nValue==val) 66 break; 67 p=p->m_pNext; 68 } 69 return p; 70 } 71 void Print(ComplexListNode* head) 72 { 73 if(!head) return; 74 ComplexListNode* p=head; 75 while(p) 76 { 77 cout<<p->m_nValue<<" "; 78 p=p->m_pNext; 79 } 80 cout<<endl; 81 p=head; 82 while(p) 83 { 84 bool flag; 85 if(p->m_pSibling) flag=true; 86 else flag=false; 87 if(flag) 88 cout<<p->m_nValue<<" 的Sibling:"<<p->m_pSibling->m_nValue<<endl; 89 else 90 cout<<p->m_nValue<<" 的Sibling是NULL."<<endl; 91 p=p->m_pNext; 92 } 93 } 94 ComplexListNode* Clone(ComplexListNode* head) 95 { 96 if(!head) return NULL; 97 ComplexListNode* p=head; 98 while(p) 99 { 100 ComplexListNode* pNext=p->m_pNext; 101 ComplexListNode* temp=new ComplexListNode(); 102 temp->m_nValue=p->m_nValue; 103 p->m_pNext=temp; 104 temp->m_pNext=pNext; 105 p=pNext; 106 } 107 p=head; 108 while(p) 109 { 110 if(p->m_pSibling) 111 p->m_pNext->m_pSibling=p->m_pSibling->m_pNext; 112 else 113 p->m_pNext->m_pSibling=NULL; 114 p=p->m_pNext->m_pNext; 115 } 116 ComplexListNode* CloneHead=Split(head); 117 return CloneHead; 118 } 119 ComplexListNode* Split(ComplexListNode* head) 120 { 121 ComplexListNode* CloneHead=NULL; 122 ComplexListNode* p=head; 123 ComplexListNode* pClone=NULL; 124 if(p) 125 { 126 CloneHead=p->m_pNext; 127 pClone=CloneHead; 128 p->m_pNext=pClone->m_pNext; 129 p=p->m_pNext; 130 } 131 while(p) 132 { 133 pClone->m_pNext=p->m_pNext; 134 pClone=pClone->m_pNext; 135 p->m_pNext=pClone->m_pNext; 136 p=p->m_pNext; 137 } 138 return CloneHead; 139 }
面试题27:二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建新的结点,只能调整数中结点的指针指向。比如
思路:
搜索二叉树,排序好的,是中序遍历。
使用递归,递归到根结点时,左子树已经是排好序的了。
递归体:
根结点和左子树中最大的结点相连即:r->left=左子树中最大的结点
根结点和右子树中最小的结点相连即:r->right=右子树中最小的结点
1 #include <iostream> 2 using namespace std; 3 struct Node 4 { 5 int m_nValue; 6 Node* m_pLeft; 7 Node* m_pRight; 8 }; 9 void CreateTree(Node*& t); 10 void MakeTree(Node*& t,int x,Node* r1,Node* r2); 11 void Print(Node* t); 12 Node* Convert(Node* r); 13 void ConvertNode(Node* t,Node** pLast); 14 int main() 15 { 16 Node* t4,*t6,*t8,*t10,*t12,*t14,*t16,*x,*y; 17 t4=t6=t8=t10=t12=t14=t16==x=y=NULL; 18 MakeTree(t4,4,x,y); MakeTree(t8,8,x,y); MakeTree(t12,12,x,y); MakeTree(t16,16,x,y); 19 MakeTree(t6,6,t4,t8); MakeTree(t14,14,t12,t16); 20 MakeTree(t10,10,t6,t14); 21 22 return 0; 23 } 24 void MakeTree(Node*& t,int x,Node* r1,Node* r2) 25 { 26 t=new Node(); 27 t->m_nValue=x; 28 t->m_pLeft=r1; 29 t->m_pRight=r2; 30 r1=r2=NULL; 31 } 32 void CreateTree(Node*& t) 33 { 34 int val; 35 cin>>val; 36 if(val==0) 37 t=NULL; 38 else 39 { 40 t=new Node(); 41 t->m_nValue=val; 42 t->m_pLeft=NULL; 43 t->m_pRight=NULL; 44 CreateTree(t->m_pLeft); 45 CreateTree(t->m_pRight); 46 } 47 } 48 void Print(Node* t) 49 { 50 if(t==NULL) 51 return; 52 cout<<t->m_nValue<<" "; 53 Print(t->m_pLeft); 54 Print(t->m_pRight); 55 } 56 Node* Convert(Node* r) 57 { 58 Node* pLast=NULL; 59 ConvertNode(r,&pLast); 60 Node* head=pLast; 61 while(head&&head->m_pLeft) 62 head=head->m_pLeft; 63 return head; 64 } 65 void ConvertNode(Node* t,Node** pLast) 66 { 67 if(!t) return; 68 Node* pCur=t; 69 if(t->m_pLeft) 70 ConvertNode(t->m_pLeft,pLast); 71 pCur->m_pLeft=*pLast; 72 if(*pLast) 73 *pLast->m_pRight=pCur; 74 *pLast=pCur; 75 if(t->m_pRight) 76 ConvertNode(t->m_pRight,pLast); 77 }
posted on 2015-06-27 15:13 VisualTracker 阅读(229) 评论(0) 编辑 收藏 举报