数据结构学习笔记(C++):二叉链表的创建与实现

 涉及二叉链表的构造、析构、四种遍历方式的详细代码及注释。

代码中对于Create函数中利用递归创建结点的过程已用图片的形式表现:

 这道小题可以看完代码并理解后在来做。

输入样例:

1 2 4 0 0 0 3 0 0

输出样例:

输入样例:

1 2 4 0 0 5 0 0 3 0 6 0 0

输出样例: 

程序代码:

//二叉链表的创建与实现
#include<iostream>

using namespace std;

struct BiNode//创建树的结点
{
	int data;//数据域
	BiNode *leftChild;//左孩子指针
	BiNode* rightChild;//右孩子指针
};

class BiTree {
public:
	BiTree() { root = Create(); };//构造函数
	~BiTree() { Release(root); };//析构函数
public:
	void PreOrder() { PreOrder(root); };//前序便历函数
	void InOrder() { InOrder(root); };//中序遍历函数
	void PostOrder() { PostOrder(root); };//后序遍历函数
	void LevelOrder();//层序遍历函数
private:
	BiNode* Create();//创建结点-构造函数调用。解释一下为什么这里用BiNode类型,因为函数的返回值是一个结点。
	void Release(BiNode* bt);//销毁结点:析构函数调用-形参一般为根节点,从根结点开始向后遍历所有子树,利用递归原理释放所有结点内存空间
	void PreOrder(BiNode* bt);//前序遍历:前序遍历函数调用-形参一般为根结点,由根结点向后遍历子树,利用递归完成树的前序遍历。
	void InOrder(BiNode* bt);//中序遍历-中序遍历函数调用-形参一般为根结点,由根结点向后遍历子树,利用递归完成树的中序遍历。
	void PostOrder(BiNode* bt);//后序遍历-后序遍历函数调用-形参一般为根结点,由根结点向后遍历子树,利用递归完成树的后序遍历。
	BiNode* root;//指向根结点的指针
};
//创建结点
BiNode* BiTree :: Create()
{
	BiNode* bt;
	int x;
	cin >> x;
	if (x == 0) bt =NULL;//如果输入的数据是零,就创建一个空树
	else {
		bt = new BiNode;
		bt->data = x;
		bt->leftChild = Create();//利用递归原理调用Create函数创建左子树
		bt->rightChild = Create();//利用递归原理调用Create函数创建右子树
	}
	return bt;
}
//销毁结点
void BiTree::Release(BiNode* bt)
{
	if (bt == NULL) return;//函数中的形参是bt,一开始导入的实参是root,如果根结点为空说明这是一棵空树,直接结束程序。
	else
	{
		Release(bt->leftChild);//递归调用,释放左子树
		Release(bt->rightChild);//递归调用,释放右子树
		delete bt;//释放根结点
	}
}
//前序遍历(中序、后序只要改变一下递归的函数和输出数据的位置即可实现)
void BiTree::PreOrder(BiNode* bt)
{
	if (bt == NULL)return;//如果传入的结点为空则程序结束
	else
	{
		cout << bt->data << '\t';//访问根结点的数据域
		PreOrder(bt->leftChild);//前序递归遍历左子树
		PreOrder(bt->rightChild);//前序递归遍历右子树
	}
}
//中序遍历
void BiTree::InOrder(BiNode* bt)
{
	if (bt == NULL)return;//如果传入的结点为空则程序结束
	else
	{
		InOrder(bt->leftChild);//前序递归遍历左子树
		cout << bt->data << '\t';//访问根结点的数据域
		InOrder(bt->rightChild);//前序递归遍历右子树
	}
}
//后序遍历
void BiTree::PostOrder(BiNode* bt)
{
	if (bt == NULL)return;//如果传入的结点为空则程序结束
	else
	{
		PostOrder(bt->leftChild);//前序递归遍历左子树
		PostOrder(bt->rightChild);//前序递归遍历右子树
		cout << bt->data << '\t';//访问根结点的数据域
	}
}
//层序遍历
void BiTree::LevelOrder()
{
	BiNode* Q[100], * q = NULL;//定义一个指针数组和临时指针变量用于接受出队的根结点的地址
	int front = -1, rear = -1;//队列的初始化
	if (root == NULL)return;//如果根结点是空的则不需要遍历,结束程序
	else
	{
		Q[++rear] = root;//根结点不为空就将其入队。

		while (rear != front)//队列存在
		{
			q = Q[++front];//出队
			cout << q->data << '\t';
			if (q->leftChild != NULL) Q[++rear] = q->leftChild;//如果出队结点的左孩子不为空,则入队
			if (q->rightChild != NULL) Q[++rear] = q->rightChild;//如果出队结点的右孩子不为空,则入队
		}
	}
}
int main()
{
	BiTree Tree;
	cout << "前序遍历结果:" << endl;
	Tree.PreOrder();
	cout << endl<<"中序遍历结果:" << endl;
	Tree.InOrder();
	cout <<endl<< "后序遍历结果:" << endl;
	Tree.PostOrder();
	cout << endl<<"层序遍历结果:" << endl;
	Tree.LevelOrder();
	return 0;
}

举例说明:

创建结点片段:

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
二叉链表是一种常见的二叉树存储结构,它由一个节点数据域、一个指向左子树的指针和一个指向右子树的指针组成。在Java中,可以通过类来实现二叉链表。下面是一个简单的二叉链表实现示例: ``` public class BinaryTreeNode { private int data; private BinaryTreeNode leftChild; private BinaryTreeNode rightChild; public BinaryTreeNode(int data) { this.data = data; this.leftChild = null; this.rightChild = null; } public int getData() { return data; } public void setData(int data) { this.data = data; } public BinaryTreeNode getLeftChild() { return leftChild; } public void setLeftChild(BinaryTreeNode leftChild) { this.leftChild = leftChild; } public BinaryTreeNode getRightChild() { return rightChild; } public void setRightChild(BinaryTreeNode rightChild) { this.rightChild = rightChild; } } ``` 在这个类中,我们定义了一个二叉树节点的数据结构,包括数据域和左右子树的指针。我们可以通过实例化这个类来创建一个二叉链表,其中每个节点都包含一个数据和指向左右子树节点的指针。 下面是一个简单的二叉链表创建和遍历示例: ``` public class BinaryTree { private BinaryTreeNode rootNode; public void createBinaryTree(int[] array) { for (int i = 0; i < array.length; i++) { insert(array[i]); } } public void insert(int data) { BinaryTreeNode newNode = new BinaryTreeNode(data); if (rootNode == null) { rootNode = newNode; } else { BinaryTreeNode currentNode = rootNode; BinaryTreeNode parentNode; while (true) { parentNode = currentNode; if (data < currentNode.getData()) { currentNode = currentNode.getLeftChild(); if (currentNode == null) { parentNode.setLeftChild(newNode); return; } } else { currentNode = currentNode.getRightChild(); if (currentNode == null) { parentNode.setRightChild(newNode); return; } } } } } public void preOrderTraversal(BinaryTreeNode currentNode) { if (currentNode != null) { System.out.print(currentNode.getData() + " "); preOrderTraversal(currentNode.getLeftChild()); preOrderTraversal(currentNode.getRightChild()); } } public void inOrderTraversal(BinaryTreeNode currentNode) { if (currentNode != null) { inOrderTraversal(currentNode.getLeftChild()); System.out.print(currentNode.getData() + " "); inOrderTraversal(currentNode.getRightChild()); } } public void postOrderTraversal(BinaryTreeNode currentNode) { if (currentNode != null) { postOrderTraversal(currentNode.getLeftChild()); postOrderTraversal(currentNode.getRightChild()); System.out.print(currentNode.getData() + " "); } } public static void main(String[] args) { int[] array = {10, 6, 14, 4, 8, 12, 16}; BinaryTree binaryTree = new BinaryTree(); binaryTree.createBinaryTree(array); System.out.print("PreOrder Traversal: "); binaryTree.preOrderTraversal(binaryTree.rootNode); System.out.println(); System.out.print("InOrder Traversal: "); binaryTree.inOrderTraversal(binaryTree.rootNode); System.out.println(); System.out.print("PostOrder Traversal: "); binaryTree.postOrderTraversal(binaryTree.rootNode); } } ``` 在这个示例中,我们先定义了一个`BinaryTree`类,其中包含了创建二叉链表、插入数据和三种遍历方式的方法。在`createBinaryTree`方法中,我们可以通过传入一个整形数组来创建一个二叉链表。在`insert`方法中,我们可以向二叉链表中插入一个数据。在三种遍历方式的方法中,我们分别实现了先序遍历、中序遍历、后序遍历。在`main`方法中,我们创建了一个二叉链表,然后分别使用三种遍历方式输出二叉树中的节点数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码骑士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值