目录
三、在二叉树中查找值为x的节点,试设计打印值为x的节点的所有祖先的算法,假设值为x的节点不多于1个
一、二叉树的基本运算的算法
#include <iostream>
using namespace std;
#define MaxSize 100
typedef char ElemType;
typedef struct node
{
ElemType data; //数据元素
struct node *lchild; //指向左孩子
struct node *rchild; //指向右孩子
} BTNode; //声明二叉树结点类型
void CreateBTree(BTNode *&b, char *str) //创建二叉树
{
BTNode *St[MaxSize], *p;
int top = -1, k, j = 0;
char ch;
b = NULL; //建立二叉树初始时为空
ch = str[j];
while (ch != '\0') //str未扫描时循环
{
switch (ch)
{
case '(': //开始处理左子树
top++;
St[top] = p;
k = 1;
break;
case ')': //子树处理完成
top--;
break;
case ',': //开始处理右子树
k = 2;
break;
default:
p = new BTNode();
p->data = ch;
p->lchild = p->rchild = NULL;
if (b == NULL) //若b为空,p置为二叉树的根节点
{
b = p;
}
else //已建立二叉树的根节点
{
switch (k)
{
case 1:
St[top]->lchild = p;
break;
case 2:
St[top]->rchild = p;
break;
}
}
}
j++;
ch = str[j];
}
}
void DestroyBTree(BTNode *&b) //销毁二叉树
{
if (b == NULL)
{
return;
}
DestroyBTree(b->lchild); //递归销毁左子树
DestroyBTree(b->rchild); //递归销毁右子树
delete b;
b = NULL;
}
BTNode *FindNode(BTNode *b, ElemType x) //查找值为x的结点
{
if (b == NULL)
{
return NULL;
}
BTNode *p;
if (b->data == x)
{
return b;
}
else
{
p = FindNode(b->lchild, x);
if (p != NULL)
{
return p;
}
return FindNode(b->rchild, x);
}
}
BTNode *LchildNode(BTNode *p) //返回p结点左孩子结点指针
{
if (p == NULL)
{
return NULL;
}
return p->lchild;
}
BTNode *RchildNode(BTNode *p) //返回p结点右孩子结点指针
{
if (p == NULL)
{
return NULL;
}
return p->rchild;
}
int BTHeight(BTNode *b) //求二叉树b的高度
{
if (b == NULL)
{
return 0;
}
else
{
int lchildh = BTHeight(b->lchild); //求左子树的高度lchildh
int rchildh = BTHeight(b->rchild); //求右子树的高度rchildh
return lchildh > rchildh ? lchildh + 1 : rchildh + 1;
}
}
void DispBTree(BTNode *b) //以括号表示法输出二叉树
{
if (b == NULL)
{
return;
}
else
{
BTNode *p = b;
cout << p->data;
if (p->lchild != NULL || p->rchild != NULL)
{
cout << '(';//有孩子结点才输出(
DispBTree(p->lchild);//递归处理左子树
if(p->rchild!=NULL)//有右孩子结点才输出,
{
cout << ',';
}
DispBTree(p->rchild);//递归处理右子树
cout << ')';//有孩子结点才输出)
}
}
}
二、二叉树各种遍历算法
先序遍历
递归
void PreOrder(BTNode *b) //先序遍历的递归算法
{
if (b == NULL)
{
return;
}
cout << b->data << " "; //访问根节点
PreOrder(b->lchild); //递归访问左子树
PreOrder(b->rchild); //递归访问右子树
}
非递归
void PreOrder1(BTNode *b) //先序非递归遍历算法
{
if (b == NULL)
{
return;
}
BTNode *p, *St[MaxSize];
int top = -1;
St[++top] = b; //根结点进栈
while (top > -1) //栈不为空时循环
{
p = St[top]; //访问该结点
top--; //退栈
cout << p->data << " ";
if (p->rchild != NULL) //有右孩子,将其进栈
{
St[++top] = p->rchild;
}
if (p->lchild != NULL) //有左孩子啊,将其进栈
{
St[++top] = p->lchild;
}
}
cout << endl;
}
中序遍历
递归
void InOrder(BTNode *b) //中序遍历的递归算法
{
if (b == NULL)
{
return;
}
InOrder(b->lchild); //递归访问左子树
cout << b->data << " "; //访问根结点
InOrder(b->rchild); //递归访问右子树
}
非递归
void InOrder1(BTNode *b) //中序非递归遍历算法
{
if (b == NULL)
{
return;
}
BTNode *p, *St[MaxSize];
int top = -1;
p = b;
while (p != NULL || top > -1)
{
while (p != NULL) //扫描结点p的所有左下结点并进栈
{
St[++top] = p;
p = p->lchild;
}
if (top > -1) //出栈
{
p = St[top--]; //出栈结点p并访问
cout << p->data << " ";
p = p->rchild;
}
}
cout << endl;
}
后序遍历
递归
void PostOrder(BTNode *b) //后序遍历的递归算法
{
if (b == NULL)
{
return;
}
PostOrder(b->lchild); //递归访问左子树
PostOrder(b->rchild); //递归访问右子树
cout << b->data << " "; //访问根结点
}
非递归
void PostOrder1(BTNode *b) //后序非递归遍历算法
{
if (b == NULL)
{
return;
}
BTNode *p, *St[MaxSize];
bool flag;
int top = -1;
do
{
while (b != NULL) //将b结点的所有左下结点进栈
{
St[++top] = b;
b = b->lchild;
}
p = NULL; //p指向当前结点的前一个已访问的结点
flag = true; //flag为真表示正在处理栈顶结点
while (top != -1 && flag)
{
b = St[top]; //取出当前的栈顶元素
if (b->rchild == p) //右子树不存在或已被访问,访问之
{
cout << b->data << " "; //访问b结点
top--;
p = b; //p指向被访问的结点
}
else
{
b = b->rchild; //b指向右子树
flag = false; //表示当前不是处理栈顶结点
}
}
} while (top != -1);
cout << endl;
}
层次遍历
void TravLevel(BTNode *b) //层次遍历
{
BTNode *Qu[MaxSize]; //定义环形队列
int front, rear; //定义队首和队尾指针
front = rear = 0; //置队列为空
if (b != NULL)
{
cout << b->data << " ";
}
rear++; //根节点进队
Qu[rear] = b;
while (rear != front) //队列不为空
{
front = (front + 1) % MaxSize;
b = Qu[front]; //出结点b
if (b->lchild != NULL) //输出左孩子并进队
{
cout << b->lchild->data << " ";
rear = (rear + 1) % MaxSize;
Qu[rear] = b->lchild;
}
if (b->rchild != NULL) //输出右孩子并进队
{
cout << b->rchild->data << " ";
rear = (rear + 1) % MaxSize;
Qu[rear] = b->rchild;
}
}
cout << endl;
}
三、在二叉树中查找值为x的节点,试设计打印值为x的节点的所有祖先的算法,假设值为x的节点不多于1个
根据题目要求,需要输出值为X的结点的所有祖先结点的值,没有对祖先结点顺序有要求。
根据二叉树种祖先的定义可知,若结点p的结点的左孩子或右孩子是结点q,则结点p是结点q的祖先;
若结点p的左孩子或右孩子是q结点的祖先,则结点p也是结点q的祖先。
设f(b,x)表示结点b是否为值是x的结点的祖先,若结点b是值为x的结点的祖先,f(b,x)返回true;否则返回flase。
当f(b,x)分为true时,输出结点p的值。
求值为X的结点所有祖先的递归模型f(b,x)如下:
f(b,x)=false 若b==NULL
f(b,x)=true 若结点b的左孩子或右孩子的data域为x
f(b,x)=false 若f(b->lchild,x)为true或f(b->rchild,x)为true
f(b,x)=false 其它情况
bool ancestor(BTNode *b, ElemType x)
{
if (b == NULL)
{
return false;
}
else if (b->lchild != NULL && b->lchild->data == x || b->rchild != NULL && b->rchild->data == x)
{
cout << b->data << " ";
return true;
}
else if (ancestor(b->lchild, x) || ancestor(b->rchild, x))
{
cout << b->data << " ";
return true;
}
else
{
return false;
}
}