• 王道数据结构——树


    先中后序遍历 递归和非递归

    层次遍历

    二叉树的中序线索化

    中序线索二叉树的中序序列(找后继)和逆中序序列(找前驱)

    1. #include
    2. #include
    3. #define Maxsize 100
    4. typedef struct BiNode
    5. {
    6. int data;
    7. struct BiNode *lchild;
    8. struct BiNode *rchild;
    9. } BiNode,*BiTree;
    10. typedef struct
    11. {
    12. BiNode* data[Maxsize];
    13. int top;
    14. }SqStack;
    15. typedef struct
    16. {
    17. BiNode* data[Maxsize];
    18. int front,rear;
    19. }SqQueue;
    20. typedef struct ThreadNode
    21. {
    22. int data;
    23. struct ThreadNode *lchild;
    24. struct ThreadNode *rchild;
    25. int ltag;
    26. int rtag;
    27. }ThreadNode,*ThreadTree;
    28. ThreadNode *pre=NULL;//全局变量pre,指向当前访问结点的前驱
    29. //以下是顺序栈的操作的代码
    30. void InitStack(SqStack &S)
    31. {
    32. S.top=-1;
    33. }
    34. bool IsEmpty(SqStack S)
    35. {
    36. if(S.top==-1) return true;
    37. else return false;
    38. }
    39. bool Push(SqStack &S,BiNode* x)
    40. {
    41. if(S.top==Maxsize-1) return false;
    42. S.data[++S.top]=x;
    43. return true;
    44. }
    45. void Pop(SqStack &S,BiNode* &x)
    46. {
    47. if(S.top==-1)
    48. {
    49. printf("栈空!\n");
    50. }
    51. x=S.data[S.top];
    52. S.top--;
    53. }
    54. void GetTop(SqStack S,BiNode* &y)
    55. {
    56. y=S.data[S.top];
    57. }
    58. void InitTree(BiTree &T)
    59. {
    60. T->data=1;
    61. T->lchild=NULL;
    62. T->rchild=NULL;
    63. }
    64. //以下是顺序循环队列操作的代码
    65. void InitQueue(SqQueue &Q)
    66. {
    67. Q.front=1;
    68. Q.rear=1;
    69. }
    70. bool IsEmpty(SqQueue Q)
    71. {
    72. if(Q.front==Q.rear) return true;
    73. else return false;
    74. }
    75. void Push(SqQueue &Q,BiNode* x)
    76. {
    77. if(Q.front==(Q.rear+1)%Maxsize)
    78. {
    79. printf("队满了\n");
    80. }
    81. Q.data[Q.rear]=x;
    82. Q.rear=(Q.rear+1)%Maxsize;
    83. }
    84. void Pop(SqQueue &Q,BiNode* &y)
    85. {
    86. if(Q.front==Q.rear)
    87. {
    88. printf("队空了\n");
    89. }
    90. y=Q.data[Q.front];
    91. Q.front=(Q.front+1)%Maxsize;
    92. }
    93. void GetTop(SqQueue Q,BiNode* &z1)
    94. {
    95. z1=Q.data[Q.front];
    96. }
    97. void GetTail(SqQueue Q,BiNode* &z2)
    98. {
    99. z2=Q.data[Q.rear-1];
    100. }
    101. int LenQueue(SqQueue Q)
    102. {
    103. // int len;
    104. // len=(Q.rear-Q.front+Maxsize)%Maxsize;
    105. // return len;
    106. return (Q.rear+Maxsize-Q.front)%Maxsize;
    107. }
    108. //以下是树的操作的代码
    109. void PreOrder1(BiTree T)
    110. {
    111. if(T!=NULL)
    112. {
    113. printf("%d ",T->data);
    114. PreOrder1(T->lchild);
    115. PreOrder1(T->rchild);
    116. }
    117. }
    118. void PreOrder2(BiTree T)
    119. {
    120. SqStack(S);
    121. InitStack(S);
    122. BiNode *p=T;
    123. while(p||!IsEmpty(S))
    124. {
    125. if(p)
    126. {
    127. printf("%d ",p->data);
    128. Push(S,p);
    129. p=p->lchild;
    130. }
    131. else
    132. {
    133. Pop(S,p);
    134. p=p->rchild;
    135. }
    136. }
    137. }
    138. void InOrder1(BiTree T)
    139. {
    140. if(T!=NULL)
    141. {
    142. InOrder1(T->lchild);
    143. printf("%d ",T->data);
    144. InOrder1(T->rchild);
    145. }
    146. }
    147. void InOrder2(BiTree T)
    148. {
    149. SqStack(S);
    150. InitStack(S);
    151. BiNode *p=T;
    152. while(p||!IsEmpty(S))
    153. {
    154. if(p)
    155. {
    156. Push(S,p);
    157. p=p->lchild;
    158. }
    159. else
    160. {
    161. Pop(S,p);
    162. printf("%d ",p->data);
    163. p=p->rchild;
    164. }
    165. }
    166. }
    167. void PostOrder1(BiTree T)
    168. {
    169. if(T!=NULL)
    170. {
    171. PostOrder1(T->lchild);
    172. PostOrder1(T->rchild);
    173. printf("%d ",T->data);
    174. }
    175. }
    176. void PostOrder2(BiTree T)
    177. {
    178. SqStack(S);
    179. InitStack(S);
    180. BiNode *p=T;
    181. BiNode *r=NULL;
    182. while(p||!IsEmpty(S))
    183. {
    184. if(p)
    185. {
    186. Push(S,p);
    187. p=p->lchild;
    188. }
    189. else
    190. {
    191. GetTop(S,p);
    192. if(p->rchild&&p->rchild!=r)
    193. {
    194. p=p->rchild;
    195. }
    196. else
    197. {
    198. Pop(S,p);
    199. printf("%d ",p->data);
    200. r=p;
    201. p=NULL;
    202. }
    203. }
    204. }
    205. }
    206. void LevelOrder(BiTree T)
    207. {
    208. SqQueue(Q);
    209. InitQueue(Q);
    210. BiNode *p;
    211. Push(Q,T);
    212. while(!IsEmpty(Q))
    213. {
    214. Pop(Q,p);
    215. printf("%d ",p->data);
    216. if(p->lchild!=NULL) Push(Q,p->lchild);
    217. if(p->rchild!=NULL) Push(Q,p->rchild);
    218. }
    219. }
    220. //以下是中序线索化的代码
    221. void InitThreadTree(ThreadTree &T)
    222. {
    223. T->data=1;
    224. T->lchild=NULL;
    225. T->rchild=NULL;
    226. }
    227. void visit(ThreadNode *q)//线索化就是让没有指向孩子的指针指向前驱或后继并修改ltag和rtag
    228. {
    229. if(q->lchild==NULL)//左指针域为空
    230. {
    231. q->lchild=pre;
    232. q->ltag=1;
    233. }
    234. if(pre!=NULL&&pre->rchild==NULL)左指针域不为空,右指针域为空
    235. {
    236. pre->rchild=q;
    237. pre->rtag=1;
    238. }
    239. pre=q;
    240. }
    241. void InThread(ThreadTree T)//中序遍历,在visit里线索化
    242. {
    243. if(T!=NULL)
    244. {
    245. InThread(T->lchild);
    246. visit(T);
    247. InThread(T->rchild);
    248. }
    249. }
    250. void CreateInThread(ThreadTree T)
    251. {
    252. pre=NULL;
    253. if(T!=NULL)
    254. {
    255. InThread(T);
    256. if(pre->rchild==NULL)//如果到了最右下的结点,在中序序列中就是最后一个结点
    257. {
    258. pre->rtag=1;
    259. }
    260. }
    261. }
    262. //中序线索二叉树的逆中序序列
    263. ThreadNode *LastNode(ThreadNode *p)
    264. {
    265. while(p->rtag==0) p=p->rchild;
    266. return p;
    267. }
    268. ThreadNode *PreNode(ThreadNode *p)
    269. {
    270. if(p->ltag==0) return LastNode(p->lchild);
    271. else return p->lchild;
    272. }
    273. void RevInOrder(ThreadNode *T)
    274. {
    275. for(ThreadNode *p=LastNode(T);p!=NULL;p=PreNode(p))
    276. {
    277. printf("%d ",p->data);
    278. }
    279. }
    280. //中序线索二叉树的中序序列
    281. ThreadNode *FirstNode(ThreadNode *p)
    282. {
    283. while(p->ltag==0) p=p->lchild;
    284. return p;
    285. }
    286. ThreadNode *NextNode(ThreadNode *p)
    287. {
    288. if(p->rtag==0) return FirstNode(p->rchild);
    289. else return p->rchild;
    290. }
    291. void InOrder3(ThreadNode *T)
    292. {
    293. for(ThreadNode *p=FirstNode(T);p!=NULL;p=NextNode(p))
    294. {
    295. printf("%d ",p->data);
    296. }
    297. }
    298. int main()
    299. {
    300. BiTree T=(BiNode*)malloc(sizeof(BiNode));
    301. // BiNode *T;
    302. InitTree(T);
    303. BiNode *p1=(BiNode*)malloc(sizeof(BiNode));
    304. p1->data=2;
    305. p1->lchild=NULL;
    306. p1->rchild=NULL;
    307. T->lchild=p1;
    308. BiNode *p2=(BiNode*)malloc(sizeof(BiNode));
    309. p2->data=3;
    310. p2->lchild=NULL;
    311. p2->rchild=NULL;
    312. T->rchild=p2;
    313. printf("递归先序序列为:");
    314. PreOrder1(T);
    315. printf("\n");
    316. printf("非递归先序序列为:");
    317. PreOrder2(T);
    318. printf("\n");
    319. printf("递归中序序列为:");
    320. InOrder1(T);
    321. printf("\n");
    322. printf("非递归中序序列为:");
    323. InOrder2(T);
    324. printf("\n");
    325. printf("递归后序序列为:");
    326. PostOrder1(T);
    327. printf("\n");
    328. printf("非递归后序序列为:");
    329. PostOrder2(T);
    330. printf("\n");
    331. printf("层次遍历序列为:");
    332. LevelOrder(T);
    333. printf("\n");
    334. ThreadTree TT=(ThreadNode*)malloc(sizeof(ThreadNode));
    335. InitThreadTree(TT);
    336. ThreadNode *p11=(ThreadNode*)malloc(sizeof(ThreadNode));
    337. p11->data=2;
    338. p11->lchild=NULL;
    339. p11->rchild=NULL;
    340. TT->lchild=p11;
    341. ThreadNode *p22=(ThreadNode*)malloc(sizeof(ThreadNode));
    342. p22->data=3;
    343. p22->lchild=NULL;
    344. p22->rchild=NULL;
    345. TT->rchild=p22;
    346. CreateInThread(TT);
    347. printf("中序线索二叉树的逆中序序列为:\n");
    348. RevInOrder(TT);
    349. printf("\n");
    350. printf("中序线索二叉树的逆中序序列为:\n");
    351. InOrder3(TT);
    352. printf("\n");
    353. return 0;
    354. }

  • 相关阅读:
    专题一:双指针【优选算法】
    Linux部署Redis Cluster高可用集群(附带集群节点添加删除以及槽位分配操作详解)
    138. 随机链表的复制
    bp神经网络的拓扑结构,bp神经网络拓扑结构图
    基于SSM框架的校园宿舍管理系统 毕业设计源码241738
    毕业设计 机器学习数学原理
    数据库设计 ER图
    GitLab 知识树(二):gitlab社区版安装
    Java_移位运算简述
    获取随机id的api接口
  • 原文地址:https://blog.csdn.net/UncleJokerly/article/details/126291486