作业-数据结构(c):二叉树的三种遍历
/*
实训07-二叉树的建立与遍历(中国行政区划)
题目:根据提供的中国所有省市区的结构图,建立相应的二叉树并实现遍历算法。
要求:用递归和非递归分别实现二叉树的前序/中序/后序三种遍历算法,并输出遍历结果。
附图:中国地域.png
[]: https://leetcode-cn.com/leetbook/read/data-structure-binary-tree/xe17x7/ "二叉树遍历图解看这里"
看上面那个链接里面有图,方便理解
三种遍历进行对比 更好理解
完整代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
struct Node* left;
struct Node* right;
char* regionName;
}node;
node* CreateBinaryNode(char* rootName) {
node* nod = malloc(sizeof(node));
if (nod != NULL) {
nod->regionName = rootName;
nod->left = NULL;
nod->right = NULL;
}
return nod;
}
node* InsertLeftNode(node* parent, node* element) {
if (parent == NULL) {
printf("父节点为空,插入失败!");
return parent;
}
if (parent->left == NULL) {
parent->left = element;
}
else {
element->left = parent->left;
parent->left = element;
}
return element;
}
node* InsertRightNode(node* parent, node* element) {
if (parent == NULL) {
printf("父节点为空,插入失败!");
return parent;
}
if (parent->right == NULL) {
parent->right = element;
}
else {
element->right = parent->right;
parent->right = element;
}
return element;
}
/// <summary>
/// 先序遍历 根--》左--》右
/// </summary>
/// <param name="ele"></param>
void PreorderTraversal(node* ele) {
if (ele != NULL) {
printf("%s\t", ele->regionName);
PreorderTraversal(ele->left);
PreorderTraversal(ele->right);
}
}
//中序遍历 左--》根--》右
void MidorderTraversal(node* ele) {
if (ele != NULL) {
MidorderTraversal(ele->left);
printf("%s\t", ele->regionName);
MidorderTraversal(ele->right);
}
}
//后序遍历 左--》右--》根
void PostorderTraversal(node* ele) {
if (ele != NULL) {
PostorderTraversal(ele->left);
PostorderTraversal(ele->right);
printf("%s\t", ele->regionName);
}
}
//函数的声明 要不然把下面那个函数移到main函数上面来 就不用写这个声明
//从上往下执行 我这样写要是不在main函数上面声明的话 就找不到ConstructorRegion这个函数了
node* ConstructorRegion();
int main() {
node* root=ConstructorRegion();
printf("先序遍历\n");
PreorderTraversal(root);
printf("\n\n中序遍历\n");
MidorderTraversal(root);
printf("\n\n后序遍历\n");
PostorderTraversal(root);
system("Pause");
}
/*构建这个二叉树可是要我老命了.....
看这个节点的构建有没有觉得很像**文件夹目录**的结构,
一般就是用树这种结构来实现的
*/
node* ConstructorRegion() {
node* root=CreateBinaryNode("中国");
node* l=InsertLeftNode(root, CreateBinaryNode("大陆"));
node* ll=InsertLeftNode(l, CreateBinaryNode("城市"));
node* lll= InsertLeftNode(ll, CreateBinaryNode("直辖"));
node* llll= InsertLeftNode(lll, CreateBinaryNode("北方"));
InsertLeftNode(llll, CreateBinaryNode("北京"));
InsertRightNode(llll, CreateBinaryNode("天津"));
node* lllr = InsertRightNode(lll, CreateBinaryNode("南方"));
InsertLeftNode(lllr, CreateBinaryNode("上海"));
InsertRightNode(lllr, CreateBinaryNode("重庆"));
node* llr = InsertRightNode(ll, CreateBinaryNode("特区"));
InsertLeftNode(llr, CreateBinaryNode("香港"));
InsertRightNode(llr, CreateBinaryNode("澳门"));
node* lr = InsertRightNode(l, CreateBinaryNode("省区"));
node* lrl = InsertLeftNode(lr, CreateBinaryNode("自治区"));
node* lrll = InsertLeftNode(lrl, CreateBinaryNode("大区"));
InsertLeftNode(lrll, CreateBinaryNode("新疆"));
InsertRightNode(lrll, CreateBinaryNode("西藏"));
node* lrlr = InsertRightNode(lrl, CreateBinaryNode("小区"));
node* lrlrl = InsertLeftNode(lrlr, CreateBinaryNode("北方"));
InsertLeftNode(lrlrl, CreateBinaryNode("内蒙"));
InsertRightNode(lrlrl, CreateBinaryNode("宁夏"));
node* lrlrr = InsertRightNode(lrlr, CreateBinaryNode("南方"));
InsertLeftNode(lrlrr, CreateBinaryNode("广西"));
node* lrr = InsertRightNode(lr, CreateBinaryNode("省份"));
node* lrrl = InsertLeftNode(lrr, CreateBinaryNode("关外"));
node* lrrll = InsertLeftNode(lrrl, CreateBinaryNode("内陆"));
InsertLeftNode(lrrll, CreateBinaryNode("黑龙江"));
InsertRightNode(lrrll, CreateBinaryNode("吉林"));
node* lrrlr = InsertRightNode(lrrl, CreateBinaryNode("沿海"));
InsertLeftNode(lrrlr, CreateBinaryNode("辽宁"));
node* lrrr = InsertRightNode(lrr, CreateBinaryNode("关内"));
node* lrrrl = InsertLeftNode(lrrr, CreateBinaryNode("内河流域"));
node* lrrrll = InsertLeftNode(lrrrl, CreateBinaryNode("黄河"));
node* lrrrlll = InsertLeftNode(lrrrll, CreateBinaryNode("上游"));
InsertLeftNode(lrrrlll, CreateBinaryNode("青海"));
InsertRightNode(lrrrlll, CreateBinaryNode("甘肃"));
node* lrrrllr = InsertRightNode(lrrrll, CreateBinaryNode("中下游"));
node* lrrrllrl = InsertLeftNode(lrrrllr, CreateBinaryNode("中游"));
InsertLeftNode(lrrrllrl, CreateBinaryNode("山西"));
InsertRightNode(lrrrllrl, CreateBinaryNode("陕西"));
node* lrrrllrr = InsertRightNode(lrrrllr, CreateBinaryNode("下游"));
InsertLeftNode(lrrrllrr, CreateBinaryNode("河南"));
InsertRightNode(lrrrllrr, CreateBinaryNode("山东"));
node* lrrrlr = InsertRightNode(lrrrl, CreateBinaryNode("长江"));
node* lrrrlrl = InsertLeftNode(lrrrlr, CreateBinaryNode("上游"));
InsertLeftNode(lrrrlrl, CreateBinaryNode("云南"));
InsertRightNode(lrrrlrl, CreateBinaryNode("四川"));
node* lrrrlrr = InsertRightNode(lrrrlr, CreateBinaryNode("中下游"));
node* lrrrlrrl = InsertLeftNode(lrrrlrr, CreateBinaryNode("中游"));
InsertLeftNode(lrrrlrrl, CreateBinaryNode("湖南"));
InsertRightNode(lrrrlrrl, CreateBinaryNode("湖北"));
node* lrrrlrrr = InsertRightNode(lrrrlrr, CreateBinaryNode("下游"));
node* lrrrlrrrl = InsertLeftNode(lrrrlrrr, CreateBinaryNode("内陆"));
InsertLeftNode(lrrrlrrrl, CreateBinaryNode("江西"));
InsertRightNode(lrrrlrrrl, CreateBinaryNode("安徽"));
node* lrrrlrrrr = InsertRightNode(lrrrlrrr, CreateBinaryNode("沿海"));
InsertLeftNode(lrrrlrrrr, CreateBinaryNode("江苏"));
node* lrrrr = InsertRightNode(lrrr, CreateBinaryNode("非流域"));
node* lrrrrl = InsertLeftNode(lrrrr, CreateBinaryNode("内陆"));
InsertLeftNode(lrrrrl, CreateBinaryNode("河北"));
InsertRightNode(lrrrrl, CreateBinaryNode("贵州"));
node* lrrrrr = InsertRightNode(lrrrr, CreateBinaryNode("沿海"));
node* lrrrrrl = InsertLeftNode(lrrrrr, CreateBinaryNode("东部"));
InsertLeftNode(lrrrrrl, CreateBinaryNode("浙江"));
InsertRightNode(lrrrrrl, CreateBinaryNode("福建"));
node* lrrrrrr = InsertRightNode(lrrrrr, CreateBinaryNode("南部"));
InsertLeftNode(lrrrrrr, CreateBinaryNode("广东"));
node* r=InsertRightNode(root, CreateBinaryNode("离岛"));
InsertLeftNode(r, CreateBinaryNode("台湾"));
InsertRightNode(r, CreateBinaryNode("海南"));
return root;
}
非递归版本
#include <stdio.h>
#include "BinaryTree.h"
typedef enum {
true=1,
false=0
}bool;
typedef struct LinkStack {
struct Node* head;
int top;
int size;
}linkStack;
bool IsFull(linkStack* stack) {
return stack->top == stack->size - 1;
}
bool IsEmpty(linkStack* stack) {
return stack->top == -1;
}
void Push(linkStack* stack,node nod) {
if (IsFull(stack)) {
node* tmp = stack->head;
stack->head=realloc(stack->head, sizeof(node) * (stack->size * 2));
if (stack->head == NULL)
{
free(tmp);
return;
}
stack->size *= 2;
}
stack->top = stack->top++;
*(stack->head + stack->top) = nod;
}
node* Pop(linkStack* stack) {
if (IsEmpty(stack))
return NULL;
return (stack->head + stack->top--);
}
node* GetPop(linkStack* stack) {
if (IsEmpty(stack))
return;
return (stack->head + stack->top);
}
linkStack* initStack() {
linkStack* head = (linkStack*)malloc(sizeof(linkStack));
if (head != NULL) {//存在申请空间失败的情况 比如内存不够的时候 上面的malloc就会返回NULL
head->top = -1;
head->head = malloc(sizeof(node) * 10);
if (head->head != NULL) {
head->size = 10;
}
}
return head;
}
///
/// 先序遍历(非递归)
///
void PreorderTraversalNon(node* root) {
linkStack* stack = initStack();
node* p = root;
while (p != NULL || !IsEmpty(stack)) {
while (p!=NULL)//找左边 只要有就先输出 再进stack中
{ //此时输出结果类似root、l、ll、lll、 (一个l表示root的左孩子、两个表示左孩子的左孩子...)
printf("%s\t", p->regionName);
Push(stack, *p);
p = p->left;
}
//此时当前stack 存的开始节点
if (!IsEmpty(stack)) {
p = Pop(stack);//此时弹出最左边最下面一个左孩子 看看他右孩子里面还有没有子节点。指针移到p->right中后 重复上面的步骤
p = p->right;
}
}
}
///
/// 中序遍历(非递归)
///
void MidorderTraversalNon(node* root) {
linkStack* stack = initStack();
node* p = root;
while (p != NULL || !IsEmpty(stack)) {
while (p != NULL)
{
Push(stack, *p);
p = p->left;
}
if (!IsEmpty(stack)) {
p = Pop(stack);
printf("%s\t", p->regionName);
p = p->right;
}
}
}
///
/// 后序遍历(非递归)
///
void PostorderTraversalNon(node* root) {
linkStack* stack = initStack();
node* p = root;
node* pre = NULL;
while (p != NULL || !IsEmpty(stack)) {
while (p != NULL)
{
//printf("%s\t", p->regionName);
Push(stack, *p);
p = p->left;
}
if (!IsEmpty(stack)) {
p = GetPop(stack);
//第二个比较条件比较的是值 因为在stack中的节点和树中的节点的地址不一样
if (p->right==NULL || p->right->regionName == pre->regionName) {
printf("%s\t", p->regionName);
Pop(stack);
pre = p;
p = NULL;
}
else {
p = p->right;
}
}
}
}
int main() {
node* root = ConstructorRegion();
PreorderTraversalNon(root);
printf("\n\n");
MidorderTraversalNon(root);
printf("\n\n");
PostorderTraversalNon(root);
}
关于#include "BinaryTree.h"文件