• 34.二叉链树的C语言实现


    目录

    (1)二叉树的数据结构

    (2)以前序序列建立二叉树

    (3)求树的结点数

    (4)求树的层数

    (5)结点查找

    (6)前序遍历(递归算法和非递归算法)

    (7)中序遍历(递归算法和非递归算法)

    (8)后序遍历(递归算法和非递归算法)

    (9)层次遍历算法

    (10)遍历过程中借助的栈和队列算法

    全部代码


    包含二叉链树的建立,计数,查找,各种遍历。

    (1)二叉树的数据结构

    1. //二叉链树的结构体定义
    2. typedef struct BiTNode{
    3. ElemType data; //数据域
    4. BiTNode *lchild; //指向左子树根节点的指针
    5. BiTNode *rchild; //指向右子树根节点的指针
    6. }BiTNode, *BiTree;

    (2)以前序序列建立二叉树

    1. //前序序列建立二叉树
    2. void CreateBiTree(BiTree &T){
    3. ElemType ch;
    4. scanf("%c", &ch);
    5. if (ch == '#')
    6. T = NULL; //保证是叶结点
    7. else{
    8. T = (BiTree)malloc(sizeof(BiTNode));
    9. T->data = ch; //生成结点
    10. CreateBiTree(T->lchild); //构造左子树
    11. CreateBiTree(T->rchild); //构造右子树
    12. }
    13. }

    (3)求树的结点数

    1. //求树的结点数(递归)
    2. int Number_Node(BiTree T){
    3. if(T==NULL)
    4. return 0;
    5. else{
    6. return Number_Node(T->lchild) + Number_Node(T->rchild) + 1;
    7. }
    8. }

    (4)求树的层数

    1. //求树的层数(递归)
    2. int Depth(BiTree T){
    3. if(T==NULL)
    4. return 0;
    5. else{
    6. return (Depth(T->lchild) >= Depth(T->rchild)) ? Depth(T->lchild) + 1 : Depth(T->rchild) + 1;
    7. }
    8. }

    (5)结点查找

    1. //查找结点,并说明它在第几层
    2. BiTree Search(BiTree T, char a, int level){
    3. if(T == NULL)
    4. return NULL;
    5. else if(T->data == a){
    6. printf("查找成功!元素在第%d层\n",level);
    7. return T;
    8. }
    9. else{
    10. Search(T->lchild, a, level + 1);
    11. Search(T->rchild, a, level + 1);
    12. }
    13. }

    (6)前序遍历(递归算法和非递归算法)

    1. //前序遍历(递归算法)
    2. void PreOrderTraverse(BiTree T){
    3. if (T!=NULL){
    4. printf("%c", T->data);
    5. PreOrderTraverse(T->lchild);
    6. PreOrderTraverse(T->rchild);
    7. }
    8. }
    9. //前序遍历(非递归算法)
    10. void PreOrderTraverse2(BiTree T){
    11. BiTree p = T; //p是遍历指针
    12. Sqstack S;
    13. InitStack(S);
    14. while(p != NULL|| !IsStackEmpty(S)){
    15. if(p){
    16. printf("%c", p->data);
    17. InsertSqstack(S, p);
    18. p = p->lchild;
    19. }
    20. else{
    21. p = DeleteSqstack(S, p);
    22. p = p->rchild;
    23. }
    24. }
    25. }

    (7)中序遍历(递归算法和非递归算法)

    1. //中序遍历(递归算法)
    2. void InOrderTraverse(BiTree T){
    3. if (T!=NULL){
    4. InOrderTraverse(T->lchild);
    5. printf("%c", T->data);
    6. InOrderTraverse(T->rchild);
    7. }
    8. }
    9. //中序遍历(非递归算法)
    10. void InOrderTraverse2(BiTree T){
    11. BiTree p = T; //p是遍历指针
    12. Sqstack S;
    13. InitStack(S);
    14. while(p||!IsStackEmpty(S)){
    15. if(p){
    16. InsertSqstack(S, p);
    17. p = p->lchild;
    18. }
    19. else{
    20. p = DeleteSqstack(S, p);
    21. printf("%c", p->data);
    22. p = p->rchild;
    23. }
    24. }
    25. }

    (8)后序遍历(递归算法和非递归算法)

    1. //后序遍历(递归算法)
    2. void PostOrderTraverse(BiTree T){
    3. if (T!=NULL){
    4. PostOrderTraverse(T->lchild);
    5. PostOrderTraverse(T->rchild);
    6. printf("%c", T->data);
    7. }
    8. }
    9. //后序遍历(非递归算法)
    10. void PostOrderTraverse2(BiTree T){
    11. Sqstack S;
    12. InitStack(S);
    13. BiTree p = T;
    14. BiTree r = NULL;
    15. while(p||!IsStackEmpty(S)){
    16. if(p){
    17. InsertSqstack(S, p);
    18. p = p->lchild;
    19. }
    20. else{
    21. p = S.data[S.top]; //读栈顶元素(但不出栈)
    22. if(p->rchild&&p->rchild!=r){
    23. p = p->rchild;
    24. }
    25. else{
    26. p = DeleteSqstack(S, p);
    27. printf("%c", p->data);
    28. r = p;
    29. p = NULL;
    30. }
    31. }
    32. }
    33. }

    (9)层次遍历算法

    1. //层次遍历
    2. void LevelOrder(BiTree T){
    3. Queue q;
    4. InitQueue(q);
    5. BiTree p = T;
    6. InsertQueue(q, p);
    7. while(!IsQueueEmpty(q)){
    8. p = DeleteQueue(q, p);
    9. printf("%c", p->data);
    10. if(p->lchild!=NULL)
    11. InsertQueue(q, p->lchild);
    12. if(p->rchild!=NULL)
    13. InsertQueue(q, p->rchild);
    14. }
    15. }

    (10)遍历过程中借助的栈和队列算法

    1. //(循环)队列和栈的数据结构
    2. typedef struct Queue{
    3. BiTree data[MAXSIZE];
    4. int front, rear; //头尾指针,队头指针指向第一个元素,队尾指针指向队尾元素的下一个元素
    5. int tag;
    6. }Queue;
    7. typedef struct Sqstack{
    8. BiTree data[MAXSIZE];
    9. int top; //栈顶指针指向栈顶元素
    10. }Sqstack;
    11. //初始化
    12. int InitQueue(Queue &a){
    13. a.front = 0;
    14. a.rear = 0;
    15. a.tag = 0; //初始队列是空
    16. return 1;
    17. }
    18. int InitStack(Sqstack &a){
    19. a.top = -1; //初始栈顶指针是-1
    20. return 1;
    21. }
    22. //判断栈和队列是否为空
    23. bool IsStackEmpty(Sqstack S){
    24. if(S.top ==-1)
    25. return true;
    26. else
    27. return false;
    28. }
    29. bool IsQueueEmpty(Queue q){
    30. if(q.tag == 0 && q.front==q.rear)
    31. return true;
    32. else
    33. return false;
    34. }
    35. //插入
    36. int InsertQueue(Queue &a, BiTree x){
    37. if(a.front == a.rear && a.tag == 1){
    38. printf("当前队列已满!");
    39. return 0;
    40. }
    41. else{
    42. a.data[a.rear] = x;
    43. a.tag = 1; //插入队列tag置1
    44. a.rear = (a.rear + 1) % MAXSIZE;
    45. return 1;
    46. }
    47. }
    48. int InsertSqstack(Sqstack &a, BiTree x){
    49. if(a.top == MAXSIZE-1){
    50. printf("当前栈已满!");
    51. return 0;
    52. }
    53. else{
    54. a.top = a.top + 1;
    55. a.data[a.top] = x;
    56. return 1;
    57. }
    58. }
    59. //删除
    60. BiTree DeleteQueue(Queue &a,BiTree x){
    61. if(a.front == a.rear && a.tag == 0){
    62. printf("当前队列已空!");
    63. }
    64. else{
    65. x = a.data[a.front];
    66. a.tag = 0; //删除队列tag置0
    67. a.front = (a.front + 1) % MAXSIZE; //front指针+1
    68. return x;
    69. }
    70. }
    71. BiTree DeleteSqstack(Sqstack &a, BiTree x){
    72. if(a.top == -1){
    73. printf("当前栈已空!");
    74. }
    75. else{
    76. x = a.data[a.top];
    77. a.top = a.top - 1;
    78. return x;
    79. }
    80. }

    全部代码

    本次验证的二叉树如下图:

    注意:输入的是扩展二叉树,也就是要告诉计算机什么是叶结点,否则将一直递归,当输入“#”时,指针指向NULL,说明是叶结点。例如对于上图,输入的是ABD##E##C##。

    1. #include
    2. #include
    3. #include
    4. #define MAXSIZE 100
    5. #define ElemType char
    6. //二叉链树的结构体定义
    7. typedef struct BiTNode{
    8. ElemType data; //数据域
    9. BiTNode *lchild; //指向左子树根节点的指针
    10. BiTNode *rchild; //指向右子树根节点的指针
    11. }BiTNode, *BiTree;
    12. //(循环)队列和栈的数据结构
    13. typedef struct Queue{
    14. BiTree data[MAXSIZE];
    15. int front, rear; //头尾指针,队头指针指向第一个元素,队尾指针指向队尾元素的下一个元素
    16. int tag;
    17. }Queue;
    18. typedef struct Sqstack{
    19. BiTree data[MAXSIZE];
    20. int top; //栈顶指针指向栈顶元素
    21. }Sqstack;
    22. //初始化
    23. int InitQueue(Queue &a){
    24. a.front = 0;
    25. a.rear = 0;
    26. a.tag = 0; //初始队列是空
    27. return 1;
    28. }
    29. int InitStack(Sqstack &a){
    30. a.top = -1; //初始栈顶指针是-1
    31. return 1;
    32. }
    33. //判断栈和队列是否为空
    34. bool IsStackEmpty(Sqstack S){
    35. if(S.top ==-1)
    36. return true;
    37. else
    38. return false;
    39. }
    40. bool IsQueueEmpty(Queue q){
    41. if(q.tag == 0 && q.front==q.rear)
    42. return true;
    43. else
    44. return false;
    45. }
    46. //插入
    47. int InsertQueue(Queue &a, BiTree x){
    48. if(a.front == a.rear && a.tag == 1){
    49. printf("当前队列已满!");
    50. return 0;
    51. }
    52. else{
    53. a.data[a.rear] = x;
    54. a.tag = 1; //插入队列tag置1
    55. a.rear = (a.rear + 1) % MAXSIZE;
    56. return 1;
    57. }
    58. }
    59. int InsertSqstack(Sqstack &a, BiTree x){
    60. if(a.top == MAXSIZE-1){
    61. printf("当前栈已满!");
    62. return 0;
    63. }
    64. else{
    65. a.top = a.top + 1;
    66. a.data[a.top] = x;
    67. return 1;
    68. }
    69. }
    70. //删除
    71. BiTree DeleteQueue(Queue &a,BiTree x){
    72. if(a.front == a.rear && a.tag == 0){
    73. printf("当前队列已空!");
    74. }
    75. else{
    76. x = a.data[a.front];
    77. a.tag = 0; //删除队列tag置0
    78. a.front = (a.front + 1) % MAXSIZE; //front指针+1
    79. return x;
    80. }
    81. }
    82. BiTree DeleteSqstack(Sqstack &a, BiTree x){
    83. if(a.top == -1){
    84. printf("当前栈已空!");
    85. }
    86. else{
    87. x = a.data[a.top];
    88. a.top = a.top - 1;
    89. return x;
    90. }
    91. }
    92. //前序序列建立二叉树
    93. void CreateBiTree(BiTree &T){
    94. ElemType ch;
    95. scanf("%c", &ch);
    96. if (ch == '#')
    97. T = NULL; //保证是叶结点
    98. else{
    99. T = (BiTree)malloc(sizeof(BiTNode));
    100. T->data = ch; //生成结点
    101. CreateBiTree(T->lchild); //构造左子树
    102. CreateBiTree(T->rchild); //构造右子树
    103. }
    104. }
    105. //求树的结点数(递归)
    106. int Number_Node(BiTree T){
    107. if(T==NULL)
    108. return 0;
    109. else{
    110. return Number_Node(T->lchild) + Number_Node(T->rchild) + 1;
    111. }
    112. }
    113. //求树的层数(递归)
    114. int Depth(BiTree T){
    115. if(T==NULL)
    116. return 0;
    117. else{
    118. return (Depth(T->lchild) >= Depth(T->rchild)) ? Depth(T->lchild) + 1 : Depth(T->rchild) + 1;
    119. }
    120. }
    121. //查找结点,并说明它在第几层
    122. BiTree Search(BiTree T, char a, int level){
    123. if(T == NULL)
    124. return NULL;
    125. else if(T->data == a){
    126. printf("查找成功!元素在第%d层\n",level);
    127. return T;
    128. }
    129. else{
    130. Search(T->lchild, a, level + 1);
    131. Search(T->rchild, a, level + 1);
    132. }
    133. }
    134. //前序遍历(递归算法)
    135. void PreOrderTraverse(BiTree T){
    136. if (T!=NULL){
    137. printf("%c", T->data);
    138. PreOrderTraverse(T->lchild);
    139. PreOrderTraverse(T->rchild);
    140. }
    141. }
    142. //前序遍历(非递归算法)
    143. void PreOrderTraverse2(BiTree T){
    144. BiTree p = T; //p是遍历指针
    145. Sqstack S;
    146. InitStack(S);
    147. while(p != NULL|| !IsStackEmpty(S)){
    148. if(p){
    149. printf("%c", p->data);
    150. InsertSqstack(S, p);
    151. p = p->lchild;
    152. }
    153. else{
    154. p = DeleteSqstack(S, p);
    155. p = p->rchild;
    156. }
    157. }
    158. }
    159. //中序遍历(递归算法)
    160. void InOrderTraverse(BiTree T){
    161. if (T!=NULL){
    162. InOrderTraverse(T->lchild);
    163. printf("%c", T->data);
    164. InOrderTraverse(T->rchild);
    165. }
    166. }
    167. //中序遍历(非递归算法)
    168. void InOrderTraverse2(BiTree T){
    169. BiTree p = T; //p是遍历指针
    170. Sqstack S;
    171. InitStack(S);
    172. while(p||!IsStackEmpty(S)){
    173. if(p){
    174. InsertSqstack(S, p);
    175. p = p->lchild;
    176. }
    177. else{
    178. p = DeleteSqstack(S, p);
    179. printf("%c", p->data);
    180. p = p->rchild;
    181. }
    182. }
    183. }
    184. //后序遍历(递归算法)
    185. void PostOrderTraverse(BiTree T){
    186. if (T!=NULL){
    187. PostOrderTraverse(T->lchild);
    188. PostOrderTraverse(T->rchild);
    189. printf("%c", T->data);
    190. }
    191. }
    192. //后序遍历(非递归算法)
    193. void PostOrderTraverse2(BiTree T){
    194. Sqstack S;
    195. InitStack(S);
    196. BiTree p = T;
    197. BiTree r = NULL;
    198. while(p||!IsStackEmpty(S)){
    199. if(p){
    200. InsertSqstack(S, p);
    201. p = p->lchild;
    202. }
    203. else{
    204. p = S.data[S.top]; //读栈顶元素(但不出栈)
    205. if(p->rchild&&p->rchild!=r){
    206. p = p->rchild;
    207. }
    208. else{
    209. p = DeleteSqstack(S, p);
    210. printf("%c", p->data);
    211. r = p;
    212. p = NULL;
    213. }
    214. }
    215. }
    216. }
    217. //层次遍历
    218. void LevelOrder(BiTree T){
    219. Queue q;
    220. InitQueue(q);
    221. BiTree p = T;
    222. InsertQueue(q, p);
    223. while(!IsQueueEmpty(q)){
    224. p = DeleteQueue(q, p);
    225. printf("%c", p->data);
    226. if(p->lchild!=NULL)
    227. InsertQueue(q, p->lchild);
    228. if(p->rchild!=NULL)
    229. InsertQueue(q, p->rchild);
    230. }
    231. }
    232. int main(){
    233. BiTree T;
    234. printf("输入二叉树的前序序列,#代表空子树:\n");
    235. CreateBiTree(T);
    236. printf("二叉树创建成功!\n");
    237. printf("二叉树的前序遍历序列是:");
    238. PreOrderTraverse(T);
    239. printf("\n");
    240. printf("二叉树的中序遍历序列是:");
    241. InOrderTraverse(T);
    242. printf("\n");
    243. printf("二叉树的后序遍历序列是:");
    244. PostOrderTraverse(T);
    245. printf("\n");
    246. printf("二叉树的层次遍历序列是:");
    247. LevelOrder(T);
    248. printf("\n");
    249. Search(T, 'D', 1); //第1个结点在第1层
    250. printf("二叉树的元素个数是:%d\n", Number_Node(T));
    251. printf("二叉树的深度是:%d\n", Depth(T));
    252. printf("二叉树的前序遍历序列(非递归)是:");
    253. PreOrderTraverse2(T);
    254. printf("\n");
    255. printf("二叉树的中序遍历序列(非递归)是:");
    256. InOrderTraverse2(T);
    257. printf("\n");
    258. printf("二叉树的后序遍历序列(非递归)是:");
    259. PostOrderTraverse2(T);
    260. printf("\n");
    261. return 0;
    262. }

    输出:

    1. 输入二叉树的前序序列,#代表空子树:
    2. ABD##E##C##
    3. 二叉树创建成功!
    4. 二叉树的前序遍历序列是:ABDEC
    5. 二叉树的中序遍历序列是:DBEAC
    6. 二叉树的后序遍历序列是:DEBCA
    7. 二叉树的层次遍历序列是:ABCDE
    8. 查找成功!元素在第3
    9. 二叉树的元素个数是:5
    10. 二叉树的深度是:3
    11. 二叉树的前序遍历序列(非递归)是:ABDEC
    12. 二叉树的中序遍历序列(非递归)是:DBEAC
    13. 二叉树的后序遍历序列(非递归)是:DEBCA
  • 相关阅读:
    APS计划排程结果的量化评价
    电脑截图怎么转换成文字?学会这个方法,轻松实现
    前端三剑客:html、css、javascript
    教育类《中学政史地》收稿方向-投稿邮箱
    Spring Boot
    在Spring Boot中使用Thymeleaf开发Web页面
    uniapp的async、await用法介绍
    win10+Android(华为)系统原生日历同步方案+Sol日历桌面显示
    pytest allure 生成报告过程
    深度学习入门(6) - 3DV 三维视觉
  • 原文地址:https://blog.csdn.net/qq_54708219/article/details/133581706