作业-数据结构(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"文件

posted @ 2021-10-27 17:50  无涯ha  阅读(193)  评论(0编辑  收藏  举报