//树的非递归三种遍历算法
//先序遍历算法
void PreOrder(BiTree* bt)
{
Stack s;
init(s)
p = bt;
while(p&&!IsEmpty(s))
{
if(p) //当p不为空的时候一直往左走并且访问
{
visit(p->data);
push(s,p) //访问完之后压入栈
p=p->lchild;
}
else //当没有左子树的时候往右走
{
pop(s,p);
p=p->rchild;
}
}
}
void MidOrder(BiTree* bt)
{
Stack s;
init(s);
while(p&&!IsEmpty(s))
{
if(p) //一直往左走
{
push(s,p); //左子树压栈
p=p->lchild;
}
else
{
pop(s,p);
visit(p);
p=p->rchild;
}
}
}
void PostOrder(BiTree* bt)
{
Stack s;
init(s);
BiTree* r = NULL;
while(p&&!IsEmpty(s))
{
if(p) //一直往左走左子树压栈
{
push(s,p);
p=p->lchild;
}
else //没有左子树的时候要访问右子树了
{
if(p->rchild&&p->rchild!=r) //当有右子树的时候且右子树没有访问过的时候
{
Gettop(s,p); //取出栈顶的根节点
p=p->rchild; //右子树压栈
push(s,p);
p=p->lchild; //转向左子树
}
else
{ //到了只有一个根节点了
pop(s,p);
visit(p); //访问根节点
r=p; //r置为访问过的p
p=NULL; //因为左子树都压入栈了所以p置空
}
}
}
}
//线索二叉树中序遍历线索二叉树
Status InOrderTraverse_Thr(BiThrTree T,function visit)
{
p = T->lchild; //p指向根节点
while(p!=T)
{
while(p->LTag==link) //当有左子树的时候往左走;
p = p->lchild;
if(!visit(p->data)) //没有左子树的时候访问根节点
return ERROR;
while(p->RTag==Thread&&p->rchild!=T) //然后访问右节点,当没有右节点或者右子树为线索的时候往右走
{
p=p->rchild;
visit(p->data);
}
p=p->rchild; //这里说明有右孩子,
}
return ok;
}
//中序遍历建立线索二叉树
Status InOrderThreading(BiThrTree& Thrt,BiThrTree T)
{
if(!(Thrt=(BiThtTree*)malloc(sizeof(BiThtTree))))
exit(0);
Thrt->LTag = Link;
Thrt->RTag = Thread;
Thrt->rchild = Thrt; //右指针回指
Thrt->lchild = T;
pre = Thrt;
InThreading(T); //中序遍历线索化
pre->rchild = Thrt;
pre->RTag = Thread;
Thrt->rchild = pre;
}
//线索化
void InThreading(BiThrTree p)
{
if(p)
{
InTreading(p->lchild); //左子树线索化
if(!p->lchild)
{
p->LTag = Thread;
p->lchild = pre;
}
if(!p->rchild)
{
p->RTag = Thread;
pre->rchild = p;
}
pre = p;
InThreading(p->rchild); //右子树线索化
}
}
//树的高度
int DepthTree(BiTree bt)
{
if(!bt)
return 0;
else if(!bt->lchild&&!bt->rchild)
return 1;
else
return 1+max(DepthTree(bt->lchild),DepthTree(bt->rchild));
}
//树的叶子节点个数
int LeaveTree(BiTree bt)
{
if(!bt)
return 0;
else
{
if(!bt->lchild&&!bt->rchild)
return 1;
else
return(LeaveTree(bt->lchild)+LeavesTree(bt->rchild));
}
}
//求树的宽度
typedef struct{
BiTree data[MAXSIZE]; //保存队列节点指针
int level[MAXSIZE]; //保存data中相同下标的节点层次
int front,rear;
}Qu;
int WidthTree(BiTree bt)
{
BiTree p;
int k,max,i,n;
Qu.front = Qu.rear = -1; //队列为空
Qu.rear++;
Qu.data[Qu.rear] = b; //根节点指针入队
Qu.level[Qu.rear] = 1; //根节点层次为1
while(Qu.front < Q.rear)
{
Qu.front++; //出队
p = Qu.data[Qu.front]; //出队节点
k = Qu.level[Qu.front]; //出队节点的层次
if(p->lchild!=NULL) //左孩子进入队列
{
Qu.rear++;
Q.data[Qu.rear] = p->rchild;
Qu.level[Qu.rear] = k+1;
}
if(p->rchild!=NULL) //右孩子进入队列
{
Q.rear++;
Q.data[Qu.rear] = p->rchild;
Qu.level[Qu.rear] = k+1;
}
}
int max = 0; //max保存同一层节点的最多个数
int i = 0;
int k = 1; //k从第一层开始查找
while(i<=Qu.rear)
{
int n = 0;
while(i<Qu.rear && Qu.level[i]==k)
{
n++; //统计第k层节点的个数
i++;
}
k=Qu.level[i];
if(n>max)
max = n; //保存最大的n
}
return max;
}
//求节点的个数
int CountNode(BiTree bt)
{
if(!bt)
return 0;
else
{
if(!bt->lchild&&!bt->rchild)
return 1;
else
return 1+CountNode(bt->lchild)+CountNode(bt->rchild);
}
}
//矩阵转置
//这个算法有一个技巧就是cpot[1] = 1
// cpot[col] = cpot[col-1]+num[col-1]
//cpot[col]表示的是第col列第一个非零元素在b.data中的位置
//num[col]表示第col列中非零元的个数
typedef struct{
int i,j;
Elemtype e;
}Triple;
typedef struct{
Triple data[MAXSIZE];
int mu,nu,tu;//矩阵的行数列数废非零元的个数
}TSMatrix;
Status FastTransposeSMatrix(TSMatrix M,TSMatrix& T)
{
T.mu = M.nu;
T.nu = M.mu;
T.tu = M.tu;
if(T.tu)
{
for(col=1;col<M.nu;++col)
num[col] = 0;
for(t=1;t<M.tu,++t)
++num[M.data[t].j]; //求M中每一列中含非零元素的个数
cpot[1] = 1;
for(col = 2;col<=M.nu;++col) //求第col列中第一个非零元在b.data的序号
cpot[col] =cpot[col-1]+num[col-1];
for(p = 1;p<M.tu;++p)
{
col = M.data[p].j;
q = cpot[col];
T.data[q].i = M.data[p].j;
T.data[q].j = M.data[p].i;
T.data[q].e = M.data[p].e;
++cpot[col];
}
return ok;
}
}