树那里代码总结


//树的非递归三种遍历算法
//先序遍历算法
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;
    }
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值