树的基础算法

  • 二叉树的存储结构
链式存储结构
typedef struct{
	ElemType data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;
  • 先序遍历
  1. 递归算法
void PreOrder(BiTree T){
	if(T!=NULL){
	visit (T);
	PreOrder(T->lchild);
	PreOrder(T->rchild);
	}
}
  1. 非递归算法
//借助栈
void PreOrder(BiTree T){
	Stack S; InitStack(S);
	while(T!=NULL||StackEmpty(S)!=NULL){
		if(T!=NULL){
			visit(T);
			pust(S,T);
			T=T->lchild;
		}else{
			pop(S,T);
			T=T->rchild;
		}
	}
}
  • 中序遍历
    1、递归算法
void InOrder(BiTree T){
	if(T!=NULL){
	InOrder(T->lchild);
	visit(T);
	InOrder(T->rchild)
	}
}

2、非递归算法

void InOrder(BiTree T){
	//借助栈
	Stack S;InitStack(S);
	while(T!=NULL||StackEmpty(s)!=NULL){
		if(T!=NULL){
			pust(S,T);
			T=T->lchild
		}else{
			pop(S,T);
			visit(T);
			T=T->rchild;
		}
	}
}
  • 后序遍历
    1、递归算法
void PostOrder(BiTree T){
	if(T!=NULL){
		PostOrder(T->lchild);
		PostOrder(T->rchild);
		visit(T);
	}
}

2、非递归算法

void PostOrder(BiTree T){
	//利用栈
	Stack S; InitStack(S);
	BitNode p=NULL;
	while(T!=NULL||StackEmpty(S)!=NULL){
		if(T!=NULL){
			push(S,T);
			T=T->lchild;
		}else {
		//读取栈顶元素
		getTop(S,T);
		if(T->rchild==NULL||T->rchild==p){//T的右孩子为空或者右孩子已经被访问过
			visit(T);
			pop(S,T);
			p=T;
			T=NULL;
		}else{
			T=T->rchild;
		}
		}
	}
}
  • 层次遍历
借助队列实现
void levelOrder(BiTree T){
	Queue Q; InitQueue(Q);
	BiTNode *p=T;
	EnQueue(Q,)
	while(QueueEmpty(Q)!=NULL){
		DeQueue(Q,p);
		visit(p);
		if(p->lchild!=NULL){
			EnQueue(Q,p->lchild);
		}
		if(p->rchild!=NULL){
			EnQueue(Q,p->rchild);
		}
	}
}
  • 二叉排序树
typedef struct BSTNode{
	ElemType data;
	struct BSTNode *lchild,*rchild;
}*BSTree
  • 二叉排序树的查找

1、递归算法

//在二叉排序树T中查找关键字为key的结点
BSTNode *BSTSearch(BSTree T,ElemType key){
	if(T==NULL) return NULL;
	else if(T->data==key) return T;
	else if(T->data<key){
		BSTNode(T->rchild,key);
	}else{
		BSTNode(T->lchild,key);
	}
}

2、非递归算法

BSTNode *BSTSearch(BSTree T,ElemType key){
	BSTNode *p=NULL;//p指针使用来指向待查找结点的双亲
	while(T!=NULL&&T->data!=key){
		p=T;
		if(T->data<key)
			T=T->rchild;
		else
			T=T->lchild;
	}
	return T;
}
  • 二叉排序树的插入算法
//递归插入
//在二叉排序树中插入关键字为key的结点
bool BST_Insert(BSTree &T,ElemType key){
	if(T==NULL){//当前待插入结点的位置为根节点,直接插入
		T=(BSTNode *)malloc(SizeOf(BSTNode));
		T->data=key;
		T->lchild=T->rchild=NULL;
		return true;
	}
	else if(T->data==key){//已存在待插入结点,则插入失败
		return false;
	}else if(T->data<key){
		BST_Insert(T->rchild,key);
	}else
		BST_Insert(T->lchild,key);
}
  • 二叉排序树的构造
//建立n个结点的二叉排序树
//用关键字数组str[]来建立二叉排序树
void creat_BSTree(BSTree &T,ElemType str[],int n){
	T=NULL;
	for(int i=0;i<n;i++){
		BST_Insert(T,str[i]);
	}
}
  • 二叉树采用二叉链表存储,设计算法求其宽度和高度
//使用层次遍历的思想
void GetWidth(BiTree T){
	Queue Q;
	int max=0,n,level=0;
	EnQueue(Q,T);//将根节点入队
	while(QueueEmpty(Q)!=NULL){
		n=Q.size();//当前队列的结点数
		level++;
		if(max<n) max=n;//记录最大结点数
		while(n!=0){
			DeQueue(Q,T);
			if(T->lchild!=NULL)
				EnQueue(Q,T->lchild);
			if(T->rchild!=NULL)
				EnQueue(Q,r->child);
			n--;
		}//while
	}
	cout<<"树的高度"<<level<<endl;
	cout<<"树的宽度"<<max<<endl;
	
}
  • 完全二叉树存储在字符型数组中,求出下标i和j两节点最近的公共祖先
char CloseAncestor(chat tree[],int i,int j){
	int p=i,q=j;
	while(p!=q){
		if(p>q)
			p=p/2;
		else
			q=q/2;
	}
	return tree[p];
}
  • 将采用二叉链表存储的二叉树的叶子结点的右孩子指针rchild按照从左到右的顺序存储成一个单链表
//利用中序遍历的算法
void Link(BiTree T){
	BiTNode *p=T,*pre=NULL,*head;
	Stack S;
	while(p!=NULL||StackEmpty(S)!=NULL){
		if(p!=NULL){
			push(S,p);
			p=p->lchild;
		}else{
			pop(S,p);
			if(p->lchild==NULL&&p->rchild==NULL){
				if(pre==NULL){
					head=p;
					pre=p;
				}else{
					pre->rchild=p;
					pre=p;
				}
			}
			p=p->rchild;
		}//else
	}//while
	pre->rchild=NULL;
}
  • 二叉树先序遍历存储在pre[l1…r1]数组中,中序遍历存储在in[l2…r2]数组中,编写算法建立该二叉树的二叉链表
BiTNode *CreateTree(char pre[],char in[],int l1,int r1,int l2,int r2){
	BiTNode *s;
	int i;
	if(l1>r1)
		return NULL;
	s=(BiTNode *)malloc(Sizeof(BiTNode));
	s->lchild=s->rchild=NULL;
	for(i=l2;i<=r2;i++){
		if(in[i]==pre[l1])
			break;//找到中序遍历中的树根结点
	}
	s->data=in[i];
	//左子树的长度i-l2,右子树的长度r2-i
	s->lchild=CreateTree(pre,in,l1+1,l1+i-l2,l2,i-1);//递归构造左子树
	s->rchild=CreateTree(pre,in,l1+i-l2+1,r1,i+1,r2);//递归构造右子树
	return s;
}
  • 对于给定的二叉排序树,将data域小于等于x的结点全部删除点
//删除以T为根节点的左子树
void Del_lchild(BSTNode &*T){
	//以中序遍历的顺序删除
	InitStack(S);
	LNode *p=T.*q;
	while(p!=NUll&&StackEmpty(S)!=NULL){
		if(p!=NULL){
			push(S,p);
			p=p->lchild;
		}
		else{
			pop(S,p);
			q=p->rchild;
			free(p);
			p=q;
		}
	}
}
void Del_main(BSTree &T,ElemType x){
	BSTNode*p;
	while(T!=NULL){
		if(T->data==x){
			Del_lchild(T->lchild);
			free(T);
			break;
		}
		else if(T->data>x){
			T=T->lchild;
		}
		else{
			Del_lchild(T->lchild);
			p=T->rchild;
			free(T);
			T=p;
		}
	}
}
  • 写一个建立二叉树的算法
void Creat_Node(BiTree &T,ElemType key[]){
	int i=0;
		if(T==NULL){
			T=(BiTree)malloc(sizeof(BiTNode));
			T->data=A[i++];
			T->lchild=T->rchild=NULL;
		}
		else if(i%2==1){
			Create_Node(T->lchild,A[i]);
		}else{
			Create_Node(T->rchild,A[i]);
		}
	}
}
  • 判断所给的二叉树是否为完全二叉树
bool JdugeComplete(BiTree T){
	//采用层次遍历来判断
	bool flag=false;
	InitQueue(Q);
	EnQueue(Q,p);
	while(QueueEmpty(Q)!=NULL){
		DeQueue(Q,T);
		if(flag==true&&(T->lchild!=NULL||T->rchild!=NULL)) return false;
		if(T->lchild!=NULL&&T->rchild!=NULL){
			EnQueue(Q,T->Lchild);
			EnQueue(Q,T->rchild);
		}
		if(T->lchild==NULL&&T->rchild!=NULL){
			return false;
		}
		if(T->lchild==NULL&&T->rchild==NULL){
			flag==true;
			
		}
		if(T->lchild!=NULL&&T->rchild==NULL){
			EnQueue(Q,T->rchild);
			flag=true;
		}
	}
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值