【学习日记】今天学习了二叉树的链式存储和层次遍历以及将顺序存储转换为链式存储
前言
测试环境为Visual Studio2019
二叉树的链式存储为二叉链表
left | data | right |
二叉链表的结点结构
一、代码内容
1.二叉树链式存储的定义
首先自己写了个队列类(其实也可以不用);
树节点模板类的定义:data-数据,left-左孩子指针,right-右孩子指针,含参构造函数;
创建结点的函数-GetBTNode()函数 创建一个树节点并分配内存,同时利用构造函数存储内容.
代码如下(示例):
//BTree.h #include <queue> #include<vector> #include<iostream> #include<list> using namespace std; template<class T> class Queue { private: public: list<T> queueL; Queue() {} ~Queue() {} int Size()const { return (queueL.size()); } bool Empty()const { return (queueL.empty()); } const T& Front()const { return queueL.front(); } void Push(const T& item) { queueL.push_back(item); } T Pop() { T item = queueL.front(); queueL.pop_front(); return(item); } }; template<class T> class BinaryTreeNode { public: T data; BinaryTreeNode* left;//指向结点的左孩子 BinaryTreeNode* right;//指向结点的右孩子 BinaryTreeNode(const T& item, BinaryTreeNode<T>* lp = nullptr, BinaryTreeNode<T>* rp = nullptr) :data(item), left(lp), right(rp) {} }; template<class T> BinaryTreeNode<T>* GetBTNode(const T& item, BinaryTreeNode<T>* lp = nullptr, BinaryTreeNode<T>* rp = nullptr)//建立一个二叉链表结点的函数 { BinaryTreeNode<T>* p; p = new BinaryTreeNode<T>(item, lp, rp); if (p == nullptr) { cout << "Memory allcation failure!" << endl; exit(1); } return p; delete p; }
2.层次遍历函数
层次遍历:从上到下,从左到右.
因为层次遍历是一层一层进行的,从当前访问的结点结构中不能直接得到下一个要访问的结点,为此引用队列做为存储二叉链表的结点指针的寄存器.
建队列,根节点入队-----若队列不为空,则从队列中删除一个结点指针(出队)-----输出其数据,并访问该指针指向的结点,(如果存在)其左右孩子指针依次入队-----重复上一步,直至队列为空
代码如下(示例):
template<class T> void Level(BinaryTreeNode<T>* t)//层次遍历 { if (t == NULL) return; Queue<const BinaryTreeNode<T>*> Q; Q.Push(t); while (!Q.Empty()) { const BinaryTreeNode<T>* p = Q.queueL.front(); Q.Pop(); cout << p->data; if (p->left) Q.Push(p->left); if (p->right) Q.Push(p->right); } }
3.顺序存储转换为链式存储(非递归算法)
与层次遍历一样仍需要一个队列充当结点的寄存器
根据树的定义:根节点为a[i],则左孩子a[2*i+1] 右孩子a[2*i+2];
1.建队列,利用数组第一个元素(a[0])建立根节点,根节点入队-----2.声明两个树节点指针,一个为parent(父母),一个为child(孩子)-----3.定义一个整型数组下标,初始值为0(int i=0)-----4.队列不为空时时:队头出队,并赋值给parent-----5.如果左孩子( a[2*i+1] )存在,则生成左孩子,并赋值给child同时入队-----6.右孩子操作同左孩子-----7.数组下标加一(i++)-----循环4~6;
代码如下(示例):
template<class T> BinaryTreeNode<T>* MakeLinked(const vector<T>& L)//非递归算法 { if (L.size() == 0) return 0; Queue<BinaryTreeNode<T>*> Q; BinaryTreeNode<T> *t= GetBTNode(L[0]); BinaryTreeNode<T>* parent, * child; Q.Push(t); int i = 0,n = L.size(); while (!Q.Empty()) { parent = Q.Pop(); if (2 * i + 1 < n && L[2 * i + 1] != T())//如果左孩子存在 { child = GetBTNode(L[2 * i + 1]);//生成左孩子 parent->left = child; Q.Push(child); } if (2 * i + 2 < n && L[2 * i + 1] != T())//如果右孩子存在 { child = GetBTNode(L[2 * i + 2]); //生成右孩子 parent->right = child; Q.Push(child); } i++; while (i< n && L[i] == T())//i是非零元素下标(找到不为空的下标) i++; } return(t); }
二、运行结果
1.main函数
用结点法创建了ABCDEF树,以及用顺序存储(vector数组)自己输入了一个树
并把这两个树层次遍历打印
//main.cpp #include<iostream> #include"BTree.h" using namespace std; int main() { vector<char> arr; for (int i = 0; i < 5; ++i) { char a; cin >>a; arr.push_back(a); } BinaryTreeNode<char>* T; BinaryTreeNode<char>* null = nullptr; BinaryTreeNode<char>* fp = GetBTNode('F'); BinaryTreeNode<char>* dp = GetBTNode('D', fp); BinaryTreeNode<char>* bp = GetBTNode('B', null, dp); BinaryTreeNode<char>* ep = GetBTNode('E'); BinaryTreeNode<char>* cp = GetBTNode('C', null, ep); BinaryTreeNode<char>* ap = GetBTNode('A', bp, cp); T=MakeLinked<char>(arr); Level(T); cout << '\t'; Level(ap); return 0; }
2.运行截图
总结
✔以上就是我今天个人的学习内容,本文仅仅简单介绍了二叉树的层次遍历和存储转化,欢迎各位大佬批评指正。(PS:求大佬教教我怎么写 顺序存储转换为链式存储(递归算法))😊😊