C语言二叉树操作

一、实验目的

  1. 掌握二叉树的逻辑结构特征和二叉链表存储结构;
  2. 掌握二叉树的遍历方法,学会灵活运用遍历算法实现二叉树的相关计算;
  3. 掌握二叉树中序遍历方法的递归和非递归实现算法;
  4. 掌握二叉树的构造方法;
  5. 二叉树中的结点信息要从终端以正确的方式输入,具体的输入和输出格式不限;
  6. 算法要具有较好的健壮性,对错误操作要做适当处理;
  7. 对二叉树做中序遍历时,要对所采用的算法类型加以说明。

二、实验任务

  1. 输入二叉树的先序序列构造相应的二叉树;
  2. 分别用递归算法和非递归算法中序遍历二叉树,输出该二叉树的中序序列;
  3. 对二叉树进行层次遍历,输出得到的结点序列;
  4. 计算二叉树中结点的总数N,度为2的结点个数N2和叶子结点个数N0;
  5. 计算二叉树的深度Height。

三、实验过程与结果

二叉树的链式存储结构

#include"stdafx.h"
#include<iostream>
#include<string>
#include<stack>
#include<queue>
using namespace std;

template<typename T>
struct BiNode{
	T date;
	BiNode<T> *LChild, *RChild;
};

template<typename T>
class BiTree {
private:
	BiNode<T>* BiTreeRoot;
public:
	BiTree() {
		BiTreeRoot = NULL;
		//createBiTree(BiTreeRoot);
	}

	void create() {
		cout << "输入数据:";
		createBiTree(BiTreeRoot);
	}
	
	void traverse() {
		PreOrderTraverse(BiTreeRoot);
	}

	void createBiTree(BiNode<T>* &p) {	//递归先序创建
		char s;
		cin >> s;
		
		if (s == '#') {
			p = NULL;
		}
		else {
			p= new BiNode<T>;
			p->date = s;
			p->LChild = p->RChild = NULL;
			createBiTree(p->LChild);
			createBiTree(p->RChild);
		}
	}
	/*
	void PreOrderTraverse(BiNode<T>*  p,int d) {	//森林递归先序遍历,同时打印层次
		if (p) {
			cout << p->date << " "<<d<<endl;
			PreOrderTraverse(p->LChild,d+1);
			PreOrderTraverse(p->RChild,d);
		}
	}
	*/
	
	void PreOrderTraverse(BiNode<T>* p) {	//递归先序遍历
		if (p) {
			cout << p->date << " ";
			PreOrderTraverse(p->LChild);
			PreOrderTraverse(p->RChild);
		}
	}
	

	void InOrderTraverse(BiNode<T>* p) {	//递归中序遍历
		if (p) {
			PreOrderTraverse(p->LChild);
			cout << p->date << " ";
			PreOrderTraverse(p->RChild);
		}
	}

	void RreOrderTraverse_N() {	//非递归先序遍历
		stack<BiNode<T>*> s;
		BiNode<T>* t = BiTreeRoot;
		while (t || !s.empty()) {
			if (t) {
				s.push(t);
				t = t->LChild;
			}
			else {
				cout << t->date << " "; 
				t = s.top();
				s.pop();
				t = t->RChild;
			}
		}
	}

	void InOrderTraverse_N() {	//非递归中序遍历
		stack<BiNode<T>*> s;
		BiNode<T>* t = BiTreeRoot;
		while (t || !s.empty()) {
			if (t) {
				s.push(t);
				t = t->LChild;
			}
			else {
				t=s.top();
				s.pop();
				cout << t->date << " ";
				t = t->RChild;
			}
		}
	}

	void LevelOrderTraverse() {				//层次遍历二叉树
		queue<BiNode<T>*> q;
		BiNode<T> *p;
		q.push(BiTreeRoot);

		while (!q.empty()) {
			p = q.front();
			q.pop();
			cout << p->date << " ";
			if (p->LChild)
				q.push(p->LChild);
			if (p->RChild)
				q.push(p->RChild);
		}
	}

	int getDeepth(BiNode<T> *p) {			//获取该树的深度
		if (!p)
			return 0;
		
		int leftdeepth = getDeepth(p->LChild);
		int rightdeepth = getDeepth(p->RChild);

		if (leftdeepth >= rightdeepth)
			return leftdeepth+1;
		else
			return rightdeepth+1;
	}

	int countLeaf(BiNode<T> *p) {		//叶子结点个数N0;
		if (!p)
			return 0;
		if (p->LChild == NULL && p->RChild == NULL)
			return 1;
		return countLeaf(p->LChild) + countLeaf(p->RChild);
	}

	int countAllNode(BiNode<T>* p) {		//统计所有节点个数
		if (!p)
			return 0;
		return countAllNode(p->LChild) + countAllNode(p->RChild)+1;
	}

	int countDoubleNode(BiNode<T>* p) {		//计算度为二的节点数
		if (p == NULL)
			return 0;
		if (p->LChild != NULL && p->RChild != NULL)
			return countDoubleNode(p->LChild) + countDoubleNode(p->RChild)+1;
		if (p->LChild == NULL && p->RChild == NULL)	//都空
			return 0;
		if (p->LChild == NULL || p->RChild == NULL)	//有一个非空
			return countDoubleNode(p->RChild)+ countDoubleNode(p->LChild);
	}

	BiNode<T> *getRoot(){
		return BiTreeRoot;
	}
};

//测试数据: ABD#G###CE##F##
int main() {
	BiTree<char> t;
	t.create();
	//t.traverse();
	cout << "\n中序遍历:" << endl;
	t.InOrderTraverse_N();
	cout << "\n层次遍历:" << endl;
	t.LevelOrderTraverse();
	//cout << "\n递归先序" << endl;
	//t.PreOrderTraverse(t.getRoot(), 0);

	cout << endl;
	cout<<"总结点数:"<<t.countAllNode(t.getRoot())<<endl;
	cout<<"叶子节点数:"<<t.countLeaf(t.getRoot())<<endl;
	cout<<"度为二的节点数:"<<t.countDoubleNode(t.getRoot())<<endl;
	cout << "深度为:" << t.getDeepth(t.getRoot()) << endl;

	return 0;
}
posted @ 2026-01-06 21:47  东血  阅读(3)  评论(0)    收藏  举报

载入天数...载入时分秒...