求树的遍历、树的叶子节点个数、树的高度、copy树

  1 #include<iostream>
  2 
  3 using namespace std;
  4 
  5 typedef struct Treenode
  6 {
  7     Treenode* leftchild;//不能定义成struct Treenode leftchild,因为这样就等于循环定义了,系统不知道该分配多少内存给该结构体
  8     Treenode* rightchild;
  9     int data;
 10 }TreeNode,*pTreeNode;
 11 
 12 //前序遍历
 13 void Pre_reverse(pTreeNode root)
 14 {
 15     if(root == NULL)
 16     {
 17         return;
 18     }
 19 
 20     //先遍历根节点
 21     cout<<root->data<<" ";
 22 
 23     //再遍历左子树
 24     Pre_reverse(root->leftchild);
 25 
 26     //最后遍历右子树
 27     Pre_reverse(root->rightchild);
 28 }
 29 
 30 //中序遍历
 31 void Mid_reverse(pTreeNode root)
 32 {
 33     if(root == NULL)
 34     {
 35         return;
 36     }
 37 
 38     //先遍历左节点
 39     Mid_reverse(root->leftchild);
 40 
 41     //再遍历根节点
 42     cout<<root->data<<" ";
 43 
 44     //最后遍历右子树
 45     Mid_reverse(root->rightchild);
 46 }
 47 
 48 //后序遍历
 49 void Aft_reverse(pTreeNode root)
 50 {
 51     if(root == NULL)
 52     {
 53         return;
 54     }
 55 
 56     //先遍历左节点
 57     Aft_reverse(root->leftchild);
 58 
 59     //再遍历右子树
 60     Aft_reverse(root->rightchild);
 61 
 62     //最后遍历根节点
 63     cout<<root->data<<" ";
 64 }
 65 
 66 //求二叉树中叶子节点的个数,存储在leafnum中
 67 void Leaf_size(pTreeNode root,int &leafnum)
 68 {
 69     if(!root)
 70     {
 71         return;
 72     }
 73 
 74     if(!root->leftchild && !root->rightchild)
 75     {
 76         leafnum++;
 77     }
 78 
 79     Leaf_size(root->leftchild,leafnum);
 80     Leaf_size(root->rightchild,leafnum);
 81 }
 82 
 83 
 84 //求二叉树的高度,存储在treehig中
 85 void Treehig_size(pTreeNode root,int &treehig)
 86 {
 87     int midtreehig1=0,midtreehig2=0;//每次递归时的中间变量,用来存储根到左子树叶子的高度和根到右子树叶子的高度
 88 
 89     if(!root)
 90     {
 91         return;
 92     }
 93 
 94     treehig++;//递归向下遍历一颗树时,当某个节点不为空时,将树的高度加1
 95     midtreehig2=treehig;
 96     if(root->leftchild)
 97     {
 98         Treehig_size(root->leftchild,treehig);
 99     }
100     midtreehig1=treehig;//midtreehig1存储根到左子树叶子的高度
101     treehig=midtreehig2;//回到这次递归左子树前树的高度
102 
103     if(root->rightchild)
104     {
105         Treehig_size(root->rightchild,treehig);
106     }
107     midtreehig2=treehig;//midtreehig2存储根到右子树叶子的高度
108 
109     treehig=midtreehig1>=midtreehig2?midtreehig1:midtreehig2;//得到这次递归树的高度
110 }
111 
112  
113 
114 //copy一颗二叉树,思想和遍历二叉树一样
115 pTreeNode Copy_tree(pTreeNode root)
116 {
117     if(root == NULL)
118     {
119         return NULL;
120     }
121 
122     //先遍历根节点
123     pTreeNode subroot=(pTreeNode)malloc(sizeof(TreeNode));
124 
125     memset(subroot,0,sizeof(TreeNode));
126 
127     subroot->data=root->data;
128     subroot->leftchild=root->leftchild;
129     subroot->rightchild=root->rightchild;
130 
131     //再遍历左子树
132     Copy_tree(root->leftchild);
133 
134     //最后遍历右子树
135     Copy_tree(root->rightchild);
136 
137     return subroot;
138 }
139 
140 int main()
141 {
142     //建立一颗树
143     TreeNode t1,t2,t3,t4,t5,t6,t7;
144     memset(&t1,0,sizeof(TreeNode));
145     memset(&t2,0,sizeof(TreeNode));
146     memset(&t3,0,sizeof(TreeNode));
147     memset(&t4,0,sizeof(TreeNode));
148     memset(&t5,0,sizeof(TreeNode));
149     memset(&t6,0,sizeof(TreeNode));
150     memset(&t7,0,sizeof(TreeNode));
151 
152     t1.data=1;
153     t2.data=2;
154     t3.data=3;
155     t4.data=4;
156     t5.data=5;
157     t6.data=6;
158     t7.data=7;
159 
160     t1.leftchild=&t2;
161     t1.rightchild=&t3;
162     t2.rightchild=&t4;
163     t3.leftchild=&t5;
164     t4.leftchild=&t6;
165     t6.leftchild=&t7;
166 
167     cout<<"前序遍历:";
168     Pre_reverse(&t1);
169     cout<<endl;
170 
171     cout<<"中序遍历:";
172     Mid_reverse(&t1);
173     cout<<endl;
174 
175     cout<<"后续遍历:";
176     Aft_reverse(&t1);
177     cout<<endl;
178 
179     //求树的叶子节点的个数
180     int leaf_num=0;
181     Leaf_size(&t1,leaf_num);
182     cout<<"树的叶子节点个数是:"<<leaf_num<<endl;
183 
184     //求树的高度
185     int tree_hig=0;
186     Treehig_size(&t1,tree_hig);
187     cout<<"树的高度是:"<<tree_hig<<endl;
188 
189     //copy树
190     pTreeNode copy_tree=Copy_tree(&t1);
191     cout<<"copy树的前序遍历:";
192     Pre_reverse(copy_tree);
193     cout<<endl;
194 
195     cout<<"copy树的中序遍历:";
196     Mid_reverse(copy_tree);
197     cout<<endl;
198 
199     cout<<"copy树的后序遍历:";
200     Aft_reverse(copy_tree);
201     cout<<endl;
202 
203     return 0;
204 }
205 
206  
207 
208 写递归程序的关键在于:分类讨论。如果满足递归到最后一层的条件(递归进行到最后一步了),会怎么这么样;否则(不满足递归到最后一层的条件,正在前往最后一层的路上),直接调用递归程序(注意传参的变化)。
原文地址:https://www.cnblogs.com/jswu-ustc/p/7801393.html