树的基本操作

1,树是一种极重要的逻辑结构,每个节点都仅有一个父亲节点。

以下以二叉树的各种算法为例理解树的结构。

1.1 二叉树的创建

BiTree CreatTRee()
{
	BiTree T;
        char c;
	c=getchar();
	if(c=='#') T=NULL;
	else{
		T=(BiTree)malloc(sizeof(BiNode));
		T->data=c;
		T->lchild=CreaTRee();
		T->rchild=CreaTRee(); 
	}	
	return T;
}
以上是以先序遍历为例,当然,随着T->data=c;语句的不同位置我们可以将其转换为后序或中序遍历。

算法并不复杂,这是递归函数较为简单的形式,如果难以理解可以想象一个只具有根节点,单左子树,单右子树的结构,套在上述函数里面用大脑跑一下流程,至于更复杂的树也是基于最基本的形式展开的。

1.2 二叉树的递归遍历

这个很简单,甚至连上面的复杂都没有,略。

1.3 二叉树的层次遍历

层次遍历的难点在于如何初始化队列的首尾指针和在出入队列的过程中首尾指针的变化情况。

void f(BiTree bt)
{
	int rear=1;
	int top=0;
	BiTree Queue[100],temp;
	Queue[0]=bt;
	while(rear!=top)
	{
		temp=Queue[top++];
		printf("%c",temp->data);
		if(temp->lchild!=NULL)
		{
			Queue[rear++]=temp->lchild;
		}
		if(temp->rchild!=NULL)
		{
			Queue[rear++]=temp->rchild;
		}
		
	}
}
思想很简单,就是不断判断当前节点有没有可以入队列的子节点。

1.4 二叉树的非递归遍历

这个一般是模拟递归栈的思想,但是需要注意的是,该函数并不是真的递归栈,该类函数在右子树入栈的时候会把根节点出栈,而普通的递归函数只有左右子树都出栈后才会把根节点出栈,需要注意。

画一个最简单的二叉树abc,a入栈->读a->b入栈->读b->b出栈且右子树为空->a出栈并把a的右子树c加入栈中

1.4.1先序及中序非递归遍历函数

void NRPreOrder(BiTree bt)
{
	BiTree STACK[100],p;
	p=bt;
	int top=0;
	while((p!=NULL)&&top!=0)){
	while(p!=NULL)
	{
		STACK[++top]=p;       //当前节点入栈 
        printf("%d",p->data); //打印节点值 
        p=p->lchild;          //向左遍历 
	}
	if(top!=0)
	{
		p=STACK[top--];       //最后的左子树出栈 
		p=p->right;           //访问右子树 
	}
}
} 
void NRMidOrder(BiTree bt)
{
	BiTree STACK[100],p;
	p=bt;
	int top=0;
	while((p!=NULL)&&top!=0)){
	while(p!=NULL)
	{
		STACK[++top]=p;
        p=p->lchild;
	}
	if(top!=0)
	{
		p=STACK[top--];
		printf("%d",p->data);
		p=p->right; 
	}
}
} 
1.4.2 后序遍历
void NRPostOrder(BiTree bt)
{
	BiTree STACK[100],p;
	p=bt;
	int top=-1;
	while((p!=NULL)&&(top!=-1))
	{
		if(p!=NULL)
		{
			STACK[++top]=p;
			p.flag=1;
			p=p->lchild;
		}
		
		else{
			p=STACK[top];
			sigh=STACK[top--]->flag;
			if(sigh==1)
			{
				STACK[++top]=p;
				p->flag=2;
				p=p->rchild;
			}
			else{
				printf("%c",p->data);
				p=NULL;
			}
		}
	}
}
后序遍历的算法更加复杂,每个节点2进2出栈,需要仔细咀嚼。

1.5 二叉树的恢复函数

明天写,吃饭去了溜了溜了

1.6 二叉树的表示函数

许多二叉树的函数只要满足基本的abc树,都可以实现其功能。

比如:

void display(BiTree &root)        //显示树形结构 
{
    if(root!=NULL)
    {
        printf("%c",root->data);
        if(root->lchild!=NULL)
        {
            printf("(");
            display(root->lchild);
        }
        if(root->rchild!=NULL)
        {
            printf(",");
            display(root->rchild);
            printf(")");
        }
    }
}
以下这个有趣的函数可以将树的结构描绘出来。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉排序也称为二叉搜索,它是一种特殊的二叉树,满足以下性质: 1. 左子中的所有节点的值均小于根节点的值; 2. 右子中的所有节点的值均大于根节点的值; 3. 左子和右子也都是二叉排序基本操作包括插入节点、删除节点和查找节点。下面是它们的实现: 1. 插入节点: 插入节点操作用于向二叉排序中插入一个新节点。从根节点开始,比较插入节点的值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。直到找到一个空位置,将新节点插入到该位置。 示例代码如下: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert_node(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert_node(root.left, val) else: root.right = insert_node(root.right, val) return root ``` 2. 删除节点: 删除节点操作用于从二叉排序中删除指定节点。分为三种情况: - 被删除节点没有子节点:直接删除即可; - 被删除节点只有一个子节点:将子节点替代被删除节点的位置; - 被删除节点有两个子节点:找到被删除节点的后继节点(右子中最小的节点),将后继节点的值复制到被删除节点,然后删除后继节点。 示例代码如下: ```python def find_min(node): while node.left is not None: node = node.left return node def delete_node(root, val): if root is None: return root if val < root.val: root.left = delete_node(root.left, val) elif val > root.val: root.right = delete_node(root.right, val) else: if root.left is None: return root.right elif root.right is None: return root.left else: successor = find_min(root.right) root.val = successor.val root.right = delete_node(root.right, successor.val) return root ``` 3. 查找节点: 查找节点操作用于在二叉排序中查找指定值的节点。从根节点开始,比较目标值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。如果找到匹配的节点,则返回该节点;如果遍历完整个仍未找到匹配的节点,则返回空。 示例代码如下: ```python def search_node(root, val): if root is None or root.val == val: return root if val < root.val: return search_node(root.left, val) else: return search_node(root.right, val) ``` 以上是二叉排序基本操作的实现。你可以根据需要调用这些函数来操作二叉排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值