需要关注的地方:
树的结构体与树的节点结构体的不同
用根节点表示一棵树,类似于链表。用一个结构体指针指向根节点,如果这个指针为空,则树也为空。
发现二叉树反而和链表比较相似
需要构建的数目
先做一个最简单的数目main中代码
效果图
完整代码:
#include<stdio.h> #include<stdlib.h> //定义结构 struct treeNode { char data; struct treeNode* Lchild; struct treeNode* Rchild; }; //创建树节点 struct treeNode* createNode(char data) { struct treeNode* newNode=(struct treeNode*)malloc(sizeof(struct treeNode)); newNode->data=data; newNode->Lchild=newNode->Rchild=NULL; return newNode; } //插入节点(给某一个节点插入左右孩子) void insertNode(struct treeNode* curNode,struct treeNode* Lchild,struct treeNode* Rchild) { curNode->Lchild=Lchild; curNode->Rchild=Rchild; } int main() { //树与节点创建 struct treeNode* Node1=createNode('A'); struct treeNode* Node2=createNode('B'); struct treeNode* Node3=createNode('C'); insertNode(Node1,Node2,Node3); printf("%c %c %c ",Node1->data,Node1->Lchild->data,Node1->Rchild->data); return 0; }
几种递归遍历:
递归部分代码:
递归遍历的完整代码:
#include<stdio.h> #include<stdlib.h> //定义结构 struct treeNode { char data; struct treeNode* Lchild; struct treeNode* Rchild; }; //创建树节点 struct treeNode* createNode(char data) { struct treeNode* newNode=(struct treeNode*)malloc(sizeof(struct treeNode)); newNode->data=data; newNode->Lchild=newNode->Rchild=NULL; return newNode; } //插入节点(给某一个节点插入左右孩子) void insertNode(struct treeNode* curNode,struct treeNode* Lchild,struct treeNode* Rchild) { curNode->Lchild=Lchild; curNode->Rchild=Rchild; } //打印节点数据(方便节点遍历) void printData(struct treeNode* curNode) { printf("%c ",curNode->data); } //先序递归遍历 void preOrder(struct treeNode* tree) { if(tree!=NULL) { printData(tree); preOrder(tree->Lchild); preOrder(tree->Rchild); } } //中序递归遍历 void midOrder(struct treeNode* tree) { if(tree!=NULL) { midOrder(tree->Lchild); printData(tree); midOrder(tree->Rchild); } } //后续递归遍历 void lastOrder(struct treeNode* tree) { if(tree!=NULL) { lastOrder(tree->Lchild); lastOrder(tree->Rchild); printData(tree); } } int main() { //树与节点创建 struct treeNode* Node1=createNode('A'); struct treeNode* Node2=createNode('B'); struct treeNode* Node3=createNode('C'); insertNode(Node1,Node2,Node3); printf("先序:"); preOrder(Node1); printf(" "); printf("中序:"); midOrder(Node1); printf(" "); printf("后序:"); lastOrder(Node1); printf(" "); return 0; }
非递归遍历(用栈实现中序遍历,满足先进后出即可):
具体的演示视频:
https://www.bilibili.com/video/av40285886?from=search&seid=8849213985246211535
非递归部分代码:
非递归完整代码:
#include<stdio.h> #include<stdlib.h> //定义结构 struct treeNode { char data; struct treeNode* Lchild; struct treeNode* Rchild; }; //创建树节点 struct treeNode* createNode(char data) { struct treeNode* newNode=(struct treeNode*)malloc(sizeof(struct treeNode)); newNode->data=data; newNode->Lchild=newNode->Rchild=NULL; return newNode; } //插入节点(给某一个节点插入左右孩子) void insertNode(struct treeNode* curNode,struct treeNode* Lchild,struct treeNode* Rchild) { curNode->Lchild=Lchild; curNode->Rchild=Rchild; } //打印节点数据(方便节点遍历) void printData(struct treeNode* curNode) { printf("%c ",curNode->data); } //非递归实现中序遍历 void midOrderByStack(struct treeNode* tree) { struct treeNode* stack[10];//先定义个栈数组,最多能装十个节点地址(实际最多三个) int stackTop=-1;//当有节点进入时,stackTop刚好等于数组下标 struct treeNode* pmove;//用它来找到所有节点 pmove=tree; while(stackTop!=-1||pmove)//栈里面有或者指向的不为空 { while(pmove) { stackTop++; stack[stackTop]=pmove; pmove=pmove->Lchild; } //左边没有了,就把根拿出来,再放右边 if(stackTop!=-1) { pmove=stack[stackTop]; printf("%c ",pmove->data); stackTop--; pmove=pmove->Rchild; } //右边有的话就找,右边的左边 } } int main() { //树与节点创建 struct treeNode* Node1=createNode('A'); struct treeNode* Node2=createNode('B'); struct treeNode* Node3=createNode('C'); insertNode(Node1,Node2,Node3); midOrderByStack(Node1); printf(" "); return 0; }
树的层次遍历: