第一步,先定义链表的链式结构:
typedef struct BiTNode {
char data ;
struct BiTNode *lchild , *rchild;
}BiTNode, *BiTree;第二部,再定义栈的链式结构结构,和栈的基本操作:
typedef struct Snode{
BiTree data;
struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
s = NULL;
return true;
}
//判断是否为空
bool Empty(LinkStack s){
if(s == NULL) return true;
return false;
}
//入栈
bool Push(LinkStack &s , BiTree e){
LinkStack p = new Snode;
p -> data = e;
p -> next = s;
s = p;
return true;
}
//出栈
bool Pop(LinkStack &s , BiTree &e){
if(Empty(s)) return false;
e = s->data;
LinkStack p = s;
s = s->next;
delete p;
return true;
}
//取栈顶元素
BiTree GetTop(LinkStack s){
return s->data;
}第三步,用树的先序序列创建二叉树:
void CreateBiTree(BiTree &T){
char ch;
cin >> ch;
if(ch == '#') {
T = NULL;
}
else {
T = new BiTNode;
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}第四部:中序遍历:
非递归的算法,就是一种用递归的思想,来代替较为浪费时间的递归,本质还是递归
仔细看看课本算法5.2 下面的图,好好理解下,先序和中序都不难,这里就不给大家细讲
void InOrderTraverse (BiTree T) {
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
// BiTree q1 = new BiTNode;
while(p || !Empty(s)){
if(p) {
Push(s,p);
p = p ->lchild;
}
else {
Pop(s,q);
cout << q->data;
p = q->rchild;
}
}
}第五步,先序遍历:
void PriorityTraverse(BiTree T){
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
// BiTree q1 = new BiTNode;
while(p || !Empty(s)){
if(p) {
Push(s, p);
cout << p->data;
p = p ->lchild;
}
else {
Pop(s,q);
p = q->rchild;
}
}
}第六步,难点:
二叉树的后序遍历:
我的思路是:
要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了 每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
所以代码如下:
void RearTraverse(BiTree T) {
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
BiTree q1 = new BiTNode;
Push(s, p);
while (!Empty(s)){
p = GetTop(s);
if ((p->lchild == NULL&&p->rchild == NULL) ||
((q == p->lchild || q == p->rchild) && q != NULL))
{
cout << p->data;
Pop(s, q1);
q = p;
}
else
{
if (p->rchild != NULL)
Push(s,p->rchild);
if (p->lchild != NULL)
Push(s, p->lchild);
}
}
}当然了,还有一种比较常见的思路,在网上可以找到大家可以看看:
第七步:二叉树的深度;
递归算法,很好理解
int Depth (BiTree T){
int n=0,m=0;
if(T == NULL) return 0;
else{
m = Depth(T->lchild);
n = Depth(T->rchild);
}
if(m > n) return m+1;
else return n+1;
}第八步:求节点的总度数:
int NodeCount(BiTree T) {
if(T == NULL) return 0;
else return NodeCount(T->lchild) + NodeCount(T->rchild)+1;
}第九步: 求一度节点度数
int one(BiTree bt)
{
if(bt)
{
int ret=0;
if(bt->lchild)
{
ret++;
}
if(bt->rchild)
{
ret++;
}
if(ret==1)
return one(bt->lchild) + one(bt->rchild) + ret;
else
return one(bt->lchild) + one(bt->rchild);
}
else
return 0;
}第十步:完工main()函数:
int main()
{
BiTree T = new BiTNode;
CreateBiTree(T);
cout << "请输入操作序号:"<<"\n";
cout << "输入1,先序遍历"<<"\n";
cout << "输入2,后序遍历" << "\n";
cout << "输入3,中序遍历" << "\n";
cout << "输入4,求树高" <<"\n";
cout << "输入5,输出,度为1,2,3的个数" << "\n";
int n ;
int count = NodeCount(T);
int on = one(T);
while(cin>>n && n){
switch (n) {
case 1:
PriorityTraverse(T);
cout << "\n";
break;
case 2:
RearTraverse(T);
cout << "\n";
break;
case 3:
InOrderTraverse(T);
cout << "\n";
break;
case 4:
cout << Depth(T) <<"\n";
break;
case 5:
cout <<(count-on+1)/2-1<<" "<< on<<" " << (count-on+1)/2<<endl;
default:
break;
}
}
//
// PriorityTraverse( T);
// P(T);
}
//abc##de#g##f###
完整代码:
//
// main.cpp
// 数据结构实验五
//
// Created by 宋玉良 on 2020/11/28.
//
#include<bits/stdc++.h>
using namespace std ;
typedef struct BiTNode {
char data ;
struct BiTNode *lchild , *rchild;
}BiTNode, *BiTree;
typedef struct Node{
BiTree btnode;
bool isfirst;
}Node , *node;
typedef struct Snode{
BiTree data;
struct Snode *next;
}Snode , *LinkStack;
//初始化
bool InitStack(LinkStack &s){
s = NULL;
return true;
}
//判断是否为空
bool Empty(LinkStack s){
if(s == NULL) return true;
return false;
}
//入栈
bool Push(LinkStack &s , BiTree e){
LinkStack p = new Snode;
p -> data = e;
p -> next = s;
s = p;
return true;
}
//出栈
bool Pop(LinkStack &s , BiTree &e){
if(Empty(s)) return false;
e = s->data;
LinkStack p = s;
s = s->next;
delete p;
return true;
}
//取栈顶元素
BiTree GetTop(LinkStack s){
return s->data;
}
LinkStack s,s1,s2;
void InOrderTraverse (BiTree T) {
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
// BiTree q1 = new BiTNode;
while(p || !Empty(s)){
if(p) {
Push(s,p);
p = p ->lchild;
}
else {
Pop(s,q);
cout << q->data;
p = q->rchild;
}
}
}
void CreateBiTree(BiTree &T){
char ch;
cin >> ch;
if(ch == '#') {
T = NULL;
}
else {
T = new BiTNode;
T->data = ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PriorityTraverse(BiTree T){
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
// BiTree q1 = new BiTNode;
while(p || !Empty(s)){
if(p) {
Push(s, p);
cout << p->data;
p = p ->lchild;
}
else {
Pop(s,q);
p = q->rchild;
}
}
}
void RearTraverse(BiTree T) {
InitStack(s);
BiTree p = new BiTNode;
p = T;
BiTree q = new BiTNode;
BiTree q1 = new BiTNode;
Push(s, p);
while (!Empty(s)){
p = GetTop(s);
if ((p->lchild == NULL&&p->rchild == NULL) ||
((q == p->lchild || q == p->rchild) && q != NULL))
{
cout << p->data;
Pop(s, q1);
q = p;
}
else
{
if (p->rchild != NULL)
Push(s,p->rchild);
if (p->lchild != NULL)
Push(s, p->lchild);
}
}
}
int NodeCount(BiTree T) {
if(T == NULL) return 0;
else return NodeCount(T->lchild) + NodeCount(T->rchild)+1;
}
int Depth (BiTree T){
int n=0,m=0;
if(T == NULL) return 0;
else{
m = Depth(T->lchild);
n = Depth(T->rchild);
}
if(m > n) return m+1;
else return n+1;
}
int one(BiTree bt)
{
if(bt)
{
int ret=0;
if(bt->lchild)
{
ret++;
}
if(bt->rchild)
{
ret++;
}
if(ret==1)
return one(bt->lchild) + one(bt->rchild) + ret;
else
return one(bt->lchild) + one(bt->rchild);
}
else
return 0;
}
int main()
{
BiTree T = new BiTNode;
cout << "请输入您要创建二叉树的先序序列(空指针用#代替)"<< endl;
CreateBiTree(T);
cout << "请输入操作序号:"<<"\n";
cout << "输入1,先序遍历"<<"\n";
cout << "输入2,后序遍历" << "\n";
cout << "输入3,中序遍历" << "\n";
cout << "输入4,求树高" <<"\n";
cout << "输入5,输出,度为0,1,2的个数" << "\n";
int n ;
int count = NodeCount(T);
int on = one(T);
while(cin>>n && n){
switch (n) {
case 1:
PriorityTraverse(T);
cout << "\n";
break;
case 2:
RearTraverse(T);
cout << "\n";
break;
case 3:
InOrderTraverse(T);
cout << "\n";
break;
case 4:
cout << Depth(T) <<"\n";
break;
case 5:
cout <<(count-on+1)/2<<" "<< on<<" " << (count-on+1)/2-1<<endl;
default:
break;
}
}
//
// PriorityTraverse( T);
// P(T);
}
//输入样例:abc##de#g##f###
//按一棵树的先序序列来输入,空指针用#代替

京公网安备 11010502036488号