c++演示二叉树的先序中序(包括递归和非递归(基于栈)的实现)后序遍历以及层次遍历(基于循环队列实现) 以及计算二叉树的深度和 用递归和非递归两种方式计算叶子结点的数目和节点的数目

不得不说c语言是真的麻烦 尤其是一个结构体里面再套一个结构体指针,这种指针的初始化稍不留神忘记了初始化,就可能导致程序的崩溃,另外c语言的判空操作 加!的话 是为null的情况 这一点跟java一点也不像,所以建议在写程序判空的时候 能带上是否为null就带上 一方面是防止自己出错,另一方面也大大增加了程序的可读性。
另外令人最反感的是 随着你程序的不断扩大 代码量越来越多 你在查错的时候 本来指针的语法问题已经让自己够不耐烦了,再不断的上翻和下翻找你的方法体会让你愈加烦躁。有时候真的想把电脑…啊啊啊
不过值得庆幸的是 在经历了一下午的调错之后 我成功的把程序的错误全部解决了 并实现了我想要的功能。我不得不感叹,c语言真的…不方便 在java的世界里 我直接new一个队列 双端的 能保证有序的什么的 管你啥时候被销毁 管你的地址在哪 我都不需关注 直接用就行了 唉 想念java的语法 但是又不得不面对c语言。就这吧。

代码如下:

/**
	演示树的先序中序(包括递归和非递归(基于栈)的实现)后序遍历 
	以及层次遍历(基于循环队列) 
	以及递归和非递归实现计算叶子结点的总数和计算结点总数 
	以及计算树的深度
	还是第一次使用到二级指针 yes yes yes!!!! 
**/
#include <iostream>
#include <stdlib.h>
#include <math.h>
#define maxSize 10 
using namespace std;
typedef struct Node{
	int data;
	struct Node *left;
	struct Node *right;
}Node, *TreeNode;
typedef struct queue{
	TreeNode *data;
	int rear;//尾指针 
	int front;//头指针 
}queue,*Queue;
typedef struct stack{
	TreeNode *data;
	int top;
}stack,*Stack; 
void initTree(TreeNode &root);
void createTree(TreeNode &root);
TreeNode createTree2(TreeNode T);//递归创建二叉树 暂时不会用 
void preOrder(TreeNode root);
void preOrder2(Stack &s, TreeNode t);
int getHeigh(TreeNode root);
void inOrder(TreeNode root);
void inOrder2(Stack &s, TreeNode root);
void postOrder(TreeNode root);
void initQueue(Queue &q);
bool isFull(Queue q);
bool isEmpty(Queue q);
void push(Queue &q, Node *node);
Node* pop(Queue &q);
void bfs(TreeNode root, Queue &q);
void leftCounts(TreeNode root, Queue &q, int &count);
int recurLeftCounts(TreeNode node);
int nodeCounts(TreeNode node);
void initStack(Stack &s);
bool stackIsEmpty(Stack s);
void add(Stack &stack, Node *node);
Node* remove(Stack &stack); 
int main(){
	TreeNode root;
	createTree(root);//创建树
	cout << "先序遍历:"; 
	preOrder(root);//先序遍历 
	cout << "\n树的高度为:" <<  getHeigh(root);
	Queue queue;
	cout << "\n层序遍历:";
	bfs(root,queue); 
	//非递归实现计算叶子节点数 
//	int count; 
//	leftCounts(root,queue,count);
//	cout << "\n叶子结点的个数:" << count;
	
	//递归实现计算叶子节点数
	int nums = recurLeftCounts(root);
	cout << "\n叶子结点的个数:" << nums;
	
	//结点的总数
	int nodeCount = nodeCounts(root);
	cout << "\n结点的总数:" << nodeCount;
	
	//初始化一个栈
	Stack stack;
	//非递归实现先序遍历
	cout << "\n非递归的先序遍历为:";
	preOrder2(stack,root);
	//非递归实现中序遍历
	cout << "\n非递归的中序遍历为:";
	inOrder2(stack,root);
	return 0;
}

//入栈操作
void add(Stack &stack, Node *node){
	if(stack->top == maxSize - 1){
		cout << "栈已满,入栈失败..."; 
		return;	
	} 
	stack->data[++stack->top] = node;
} 

//出栈操作
Node* remove(Stack &stack){
	if(stackIsEmpty(stack)){
		cout << "栈为空,出栈失败...";
	}
//	Node *tmp = stack->data[stack->top];
//	stack->top--;
//	return tmp;
	return stack->data[stack->top--];
}
//判断栈是否为空
bool stackIsEmpty(Stack s){
	return s->top == -1;
} 
//判断队列是否为空
bool isEmpty(Queue q){
	return q->rear == q->front;
} 
//判断队列是否已满
bool isFull(Queue q){
	return (q->rear + 1) % maxSize == q->front;
}
 
//入队
void push(Queue &q, Node *node){
	if(isFull(q)){
		cout << "\n队列已满,加入失败...";
		return;
	} 
	q->data[q->rear] = node;
	q->rear = (q->rear + 1) % maxSize;
}

//出队
Node* pop(Queue &q){
	if(isEmpty(q)){
		cout << "\n队列为空,出队失败...";
		return NULL;
	}
	Node *node = q->data[q->front];
	q->front = (q->front + 1) % maxSize;
	return node;
}

//计算结点的个数  递归
int nodeCounts(TreeNode node){
	return !node ? 0 : nodeCounts(node->left) + nodeCounts(node->right) + 1;
} 
//计算叶子结点数 非递归 
void leftCounts(TreeNode root, Queue &q, int &count){
	if(root) push(q,root);
	while(!isEmpty(q)){
		Node *node = pop(q);
		if(!node->left && !node->right) {
			count++;
			cout << "\n叶子结点:" << node->data;  
		}
		if(node->left) push(q,node->left);
		if(node->right) push(q,node->right);
	}
}

//计算叶子结点数目  递归实现
int recurLeftCounts(TreeNode node){
	if(!node) return 0;
	if(!node->left && !node->right) return 1;
	return recurLeftCounts(node->left) + recurLeftCounts(node->right);	
} 
//层次遍历 
void bfs(TreeNode root, Queue &q){
	initQueue(q);//初始化队列
	if(root) push(q,root);
	while(!isEmpty(q)){
		Node *node = pop(q);
		cout << node->data << " ";
		if(node->left) push(q,node->left);
		if(node->right) push(q,node->right);
	}
} 
 
//计算深度 
int getHeigh(TreeNode root){
	return !root ? 0 : max(getHeigh(root->left)
						,getHeigh(root->right)) + 1;
}

//递归创建二叉树 
TreeNode createTree2(TreeNode T){
    char ch;
    T=(TreeNode)malloc(sizeof(Node));
    scanf("%c",&ch);
    if(ch == '#') return 0;
    T->data=ch;
    T->left=createTree2(T->left);
    T->right=createTree2(T->right);
    return T;
}

//非递归实现先序遍历
void preOrder2(Stack &s, TreeNode t){
	TreeNode p = t;
	initStack(s);
	while(p || !stackIsEmpty(s)){
		if(p){
			cout << p->data << " ";
			add(s,p);
			p = p->left;
		} else{
			p = remove(s);
			p = p->right;
		}
	}	
} 

//先序遍历 
void preOrder(TreeNode root){
	if(!root) return;
	cout << root->data << " ";
	preOrder(root->left);
	preOrder(root->right);
}

//非递归实现中序遍历
void inOrder2(Stack &s, TreeNode root){
	TreeNode p = root;
	initStack(s);
	while(p || !stackIsEmpty(s)){
		if(p){
			add(s,p);
			p = p->left;
		} else{
			p = remove(s);
			cout << p->data << " ";
			p = p->right;
		}
	}
} 
//中序遍历 
void inOrder(TreeNode root){
	if(!root) return;
	inOrder(root->left);
	cout << root->data << " ";
	inOrder(root->right);
}
//后序遍历 
void postOrder(TreeNode root){
	if(!root) return;
	postOrder(root->left);
	postOrder(root->right);
	cout << root->data << " ";
}
//创建二叉树 
void createTree(TreeNode &root){
	initTree(root);//初始化树
	Node *node1 = (Node*)malloc(sizeof(Node));
	Node *node2 = (Node*)malloc(sizeof(Node));
	Node *node3 = (Node*)malloc(sizeof(Node));
	Node *node4 = (Node*)malloc(sizeof(Node));
	Node *node5 = (Node*)malloc(sizeof(Node));
	Node *node6 = (Node*)malloc(sizeof(Node));
	node1->data = 1;
	node2->data = 2;
	node3->data = 3;
	node4->data = 4;
	node5->data = 5;
	node6->data = 6;
	root->left = node1;
	root->right = node2;
	node2->left = NULL;
	node2->right = NULL;
	node1->left = node3;
	node1->right = node4;
	node4->left = NULL;
	node4->right = NULL;
	node3->left = node5;
	node3->right = NULL;
	node5->right = node6;
	node5->left = NULL;
	node6->left = NULL;
	node6->right = NULL;
}
//初始化栈
void initStack(Stack &s){
	s = (Stack)malloc(sizeof(stack));
	s->top = -1;
	s->data = (TreeNode*)malloc(sizeof(Node) * maxSize);
}
 
//初始化队列 
void initQueue(Queue &q){
	q = (Queue)malloc(sizeof(queue));//初始化头指针 
	q->rear = 0;//指向队尾元素的下一个位置
	q->front = 0;
	q->data = (Node**)malloc(sizeof(Node) * maxSize);
	//Node** 还可以写成 TreeNode *  二级指针!!!; 
}

//初始化树 
void initTree(TreeNode &root){
	root = (TreeNode)malloc(sizeof(Node));
	root->left = NULL;
	root->right = NULL;
	root->data = 99;
}

运行结果截图如下:
在这里插入图片描述

改进部分

另外我今天又改进了我的程序 就是使用c++库里面写好的一些数据结构,也就是集合 来实现我的功能,这将为我去实现某些功能提供极大的便利之处.第一次接触c语言的集合.哈哈,除了方法比较少外,但是至少可以实现我想要的功能.这是非常赞的地方. 以下是我用队列去实现树的广度优先遍历.
代码如下:

#include<queue>
#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct Node{
	int data;
	struct Node *left;
	struct Node *right;
}Node, *TreeNode;
void createTree(TreeNode &root);
void initTree(TreeNode &root);
int main(){
	TreeNode root;
	createTree(root);//创建树
	queue<TreeNode> q; 
	if(root) q.push(root);
	TreeNode node;
	while(!q.empty()){
		node = q.front();
		cout << node->data << " "; 
		q.pop();
		if(node->left) q.push(node->left);
		if(node->right) q.push(node->right); 
	}
}
//创建二叉树 
void createTree(TreeNode &root){
	initTree(root);//初始化树
	Node *node1 = (Node*)malloc(sizeof(Node));
	Node *node2 = (Node*)malloc(sizeof(Node));
	Node *node3 = (Node*)malloc(sizeof(Node));
	Node *node4 = (Node*)malloc(sizeof(Node));
	Node *node5 = (Node*)malloc(sizeof(Node));
	Node *node6 = (Node*)malloc(sizeof(Node));
	node1->data = 1;
	node2->data = 2;
	node3->data = 3;
	node4->data = 4;
	node5->data = 5;
	node6->data = 6;
	root->left = node1;
	root->right = node2;
	node2->left = NULL;
	node2->right = NULL;
	node1->left = node3;
	node1->right = node4;
	node4->left = NULL;
	node4->right = NULL;
	node3->left = node5;
	node3->right = NULL;
	node5->right = node6;
	node5->left = NULL;
	node6->left = NULL;
	node6->right = NULL;
}
//初始化树 
void initTree(TreeNode &root){
	root = (TreeNode)malloc(sizeof(Node));
	root->left = NULL;
	root->right = NULL;
	root->data = 99;
} 

运行结果如下:
在这里插入图片描述
更新一下
今天又实现了二叉树的后序遍历非递归实现(基于栈结构以及前驱结点)
核心代码如下:

//非递归实现后序遍历
void postOrder2(Stack &s,TreeNode root){
	initStack(s);
	TreeNode t = root;
	TreeNode p = NULL;
	while(t || !stackIsEmpty(s)){
		if(t){
			add(s,t);//入栈 
			t = t->left;	
		} else{
			t = peek(s);//查看栈顶元素,并赋给t结点 
			if(t->right && t->right != p){
				t = t->right;
			} else{
				t = remove(s);//出栈 
				cout << t->data << " ";
				p = t;
				t = NULL;
			}
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值