数据结构之树的操作
数据结构中树的操作,很多时候我们不会自己写些底层的树算法,有很多的函数库已经实现了相关的算法并且性能较好,但是理解树的含义也尤为重要,下面是二叉树的四种遍历算法和相关的一些算法,本文给出都是非递归算法。
1.前序遍历(根左右)
void PreOrderN(BTreeNode * BT)
{
const int MS = 10;
BTreeNode * s[MS]; //用数组来模拟栈
int top = -1;
BTreeNode * p = BT;
while(top!=-1 || p!=NULL) //栈为空或节点为空
{
while(p!=NULL)
{
count<<p->data<<" ";
if(p->right!= NULL)
{
top++;
s[top] = p->right; //将右孩子入栈
}
p = p->left;
}
if(top!= -1) //栈是否为空
{
p = s[top];
top--;
}
}
}
const int MS = 10;
BTreeNode * s[MS]; //用数组来模拟栈
int top = -1;
BTreeNode * p = BT;
while(top!=-1 || p!=NULL) //栈为空或节点为空
{
while(p!=NULL)
{
count<<p->data<<" ";
if(p->right!= NULL)
{
top++;
s[top] = p->right; //将右孩子入栈
}
p = p->left;
}
if(top!= -1) //栈是否为空
{
p = s[top];
top--;
}
}
}
2.中序遍历(左根右)
void InOrderN(BTreeNode * BT)
{
const int MS = 10;
BTreeNode * s[MS];
int top = -1;
BTreeNode * p = BT;
while(top!=-1 || p!=NULL)
{
while(p!=NULL)
{
top++;
s[top]= p;
p = p->left; //将左孩子先入栈
}
if(top!=-1)
{
p = s[top];
top--;
count<<p->data<<" ";
p=p->right;
}
}
{
const int MS = 10;
BTreeNode * s[MS];
int top = -1;
BTreeNode * p = BT;
while(top!=-1 || p!=NULL)
{
while(p!=NULL)
{
top++;
s[top]= p;
p = p->left; //将左孩子先入栈
}
if(top!=-1)
{
p = s[top];
top--;
count<<p->data<<" ";
p=p->right;
}
}
}
3.后序遍历(左右根)
void PostOrderN(BTreeNode * BT)
{
const int MS =10;
BTreeNode * s[MS];
int top = -1;
BTreeNode * p = BT;
while(top!= -1 || p!=NULL)
{
while(p!=NULL)
{
top++;
s[top] = p;
if(p->left)
p = p->left;
else
p = p->right;
}
p = s[top];
top--;
count<<p->data<<" ";
while(top!=-1 && s[top]->right == p) //先输出右孩子,再输出父节点
{
p = s[top--];
count<<p->data<<" ";
}
if(top!= -1)
p = s[top]->right;
else
p = NULL;
}
}
const int MS =10;
BTreeNode * s[MS];
int top = -1;
BTreeNode * p = BT;
while(top!= -1 || p!=NULL)
{
while(p!=NULL)
{
top++;
s[top] = p;
if(p->left)
p = p->left;
else
p = p->right;
}
p = s[top];
top--;
count<<p->data<<" ";
while(top!=-1 && s[top]->right == p) //先输出右孩子,再输出父节点
{
p = s[top--];
count<<p->data<<" ";
}
if(top!= -1)
p = s[top]->right;
else
p = NULL;
}
}
4.层次遍历
void LevelOrderN(BTreeNode * BT)
{
const int MaxSize = 30;
BTreeNode * Q[MaxSize]; //模拟一个队列
int front = 0,rear = 0;
BTreeNode * p ;
if(BT!=NULL)
{
rear = (rear + 1)%MaxSize;
Q[rear] = BT;
}
while(front!=rear) //队列为空
{
front = (front + 1)%MaxSize; //出队
p= Q[front];
count<<p->data<<" " ;
if(p->left!=NULL)
{
rear = (rear+1)%MaxSize;
Q[rear] = p->left;
}
if(p->right != NULL)
{
rear = (rear +1)%MaxSize;
Q[rear] = p->right;
}
}
}
const int MaxSize = 30;
BTreeNode * Q[MaxSize]; //模拟一个队列
int front = 0,rear = 0;
BTreeNode * p ;
if(BT!=NULL)
{
rear = (rear + 1)%MaxSize;
Q[rear] = BT;
}
while(front!=rear) //队列为空
{
front = (front + 1)%MaxSize; //出队
p= Q[front];
count<<p->data<<" " ;
if(p->left!=NULL)
{
rear = (rear+1)%MaxSize;
Q[rear] = p->left;
}
if(p->right != NULL)
{
rear = (rear +1)%MaxSize;
Q[rear] = p->right;
}
}
}
5.判断一棵树是否为完全二叉树
int IsCompleteBit(BTreeNode * BT)
{
int flag = 0;
BTreeNode * p;
if(BT == NULL)
return 1;
InitQueue(Q);
EnQueue(Q,BT);
while(!QueueEmpty(Q))
{
DeQueue(Q,p);
if(p->lchild && !flag)
EnQueue(Q,p->lchild);
else if(p->lchild)
return 0;
else
flag = 1;
if(p->rchild && !flag)
EnQueue(Q,p->rchild);
else if(p->rchild)
return 0;
else
flag = 1;
}
return 1;
{
int flag = 0;
BTreeNode * p;
if(BT == NULL)
return 1;
InitQueue(Q);
EnQueue(Q,BT);
while(!QueueEmpty(Q))
{
DeQueue(Q,p);
if(p->lchild && !flag)
EnQueue(Q,p->lchild);
else if(p->lchild)
return 0;
else
flag = 1;
if(p->rchild && !flag)
EnQueue(Q,p->rchild);
else if(p->rchild)
return 0;
else
flag = 1;
}
return 1;
}
6.判断一棵树是否为满二叉树
int IsFullBit(BTreeNode * BT)
{
const int MaxSize = 30;
BTreeNode * Q[MaxSize];
BTreeNode * p ;
int deepth,count,front,rear;
if(BT)
{
deepth = 0;
count = 0;
front = 0;
rear = 0;
Q[front] = BT;
lastNode = 1;
while(front != rear)
{
p = Q[front++];
count++;
if(p->lchild)
Q[rear++] = p->lchild;
if(p->rchild)
Q[rear++] = p->rchild;
if(front == lastNode)
{
deepth++;
if(count!=pow(2,deepth-1)) //满足每一层的节点数n = 2^(h-1)
return 0;
lastNode = rear;
count = 0;
}
}
}
}
const int MaxSize = 30;
BTreeNode * Q[MaxSize];
BTreeNode * p ;
int deepth,count,front,rear;
if(BT)
{
deepth = 0;
count = 0;
front = 0;
rear = 0;
Q[front] = BT;
lastNode = 1;
while(front != rear)
{
p = Q[front++];
count++;
if(p->lchild)
Q[rear++] = p->lchild;
if(p->rchild)
Q[rear++] = p->rchild;
if(front == lastNode)
{
deepth++;
if(count!=pow(2,deepth-1)) //满足每一层的节点数n = 2^(h-1)
return 0;
lastNode = rear;
count = 0;
}
}
}
}
对于树的操作基本的包括这几种遍历方法,掌握了遍历算法,对于计算叶子节点也好,对节点求值也好,插入也好,都需要准确找到需要的位置。树的操作一般会用到堆栈和队列,这两种非线性的数据结构也是需要掌握的。