《数据结构与算法分析:C语言描述》习题4.10(实现二叉查找树)

4.10

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/* 二叉查找树 p80
	1.假设二叉树中个元素互异
	2.都是整数
*/
typedef struct BiTreeNode{
	int data;
	struct BiTreeNode* pLeft; //左节点
	struct BiTreeNode* pRight; //右节点
}SearchTree,*PtrSearchTree;
typedef PtrSearchTree PtrTreeNode;
typedef SearchTree TreeNode;
/*返回类型为PtrTreeNode表示返回树的一个节点,返回类型为PtrSearchTree表示返回树的根节点*/

void makeEmpty(PtrSearchTree pTree);
PtrSearchTree initTree(void); //初始化一棵树,图4-15(左)
PtrTreeNode find(int val, PtrSearchTree pTree); //在树中找到值为val的元素的节点
PtrTreeNode findMinNode(PtrSearchTree pTree); //寻找树的最小值的节点
PtrTreeNode findMaxNode(PtrSearchTree pTree); //寻找树的最大值的节点
PtrSearchTree Insert(int val, PtrSearchTree pTree); // 插入操作,返回插入后的新树的根
                                                  //若val在树内, 则什么也不做
PtrTreeNode newTreeNode(int val); //创建一个data=val,孩子均为NULL的新节点
PtrSearchTree Delete(int val, PtrSearchTree pTree); //删除val,返回删除后的新树的根
void inorderTraversal(PtrSearchTree pTree); //中序遍历
void showTree(PtrSearchTree pTree); //输出树的元素(中序遍历)

int main(void) {
	//初始树可以先pTree=NULL;再使用Insert
	PtrSearchTree pTree = initTree();
	showTree(pTree);
	pTree = Insert(6, pTree); //p80,图4-21(右)
	showTree(pTree);
	pTree = Delete(3, pTree);
	showTree(pTree);

	return 0;
}
void makeEmpty(PtrSearchTree pTree) {//清空一棵树

	if(pTree != NULL) {
		makeEmpty(pTree->pLeft);
		makeEmpty(pTree->pRight);
		free(pTree);
	}
	return;
}
PtrSearchTree initTree(void) {//初始化一棵树,图4-15(左)
	PtrSearchTree root = newTreeNode(6);//根节点
	
	PtrTreeNode p1 = newTreeNode(2);
	PtrTreeNode p2 = newTreeNode(8);
	PtrTreeNode p3 = newTreeNode(1);
	PtrTreeNode p4 = newTreeNode(4);
	PtrTreeNode p5 = newTreeNode(3);

	root->pLeft = p1;
	root->pRight = p2;
	p1->pLeft = p3;
	p1->pRight = p4;
	p4->pLeft = p5;

	return root;
}
PtrTreeNode find(int val, PtrSearchTree pTree) {//在树中找到值为val的元素的节点

	if (pTree == NULL)
		return NULL;
	if (val > pTree->data)
		return find(val, pTree->pRight);
	if (val < pTree->data)
		return find(val, pTree->pLeft);
	else
		return pTree;
	
}
PtrTreeNode findMinNode(PtrSearchTree pTree) {//寻找数的最小值的节点

	if (pTree == NULL)
		return NULL;
	
	if (pTree->pLeft != NULL)
		return findMinNode(pTree->pLeft);
	else
		return pTree;

}
PtrTreeNode findMaxNode(PtrSearchTree pTree) {//寻找树的最大值的节点
	if (pTree == NULL)
		return NULL;

	if (pTree->pRight != NULL)
		return findMaxNode(pTree->pRight);
	else
		return pTree;
}
PtrSearchTree Insert(int val, PtrSearchTree pTree) {//插入操作,若val在树内,则什么也不做

	if (pTree == NULL) 
		pTree = newTreeNode(val);
	if (val > pTree->data)
		pTree->pRight = Insert(val, pTree->pRight);
	if (val < pTree->data)
		pTree->pLeft = Insert(val, pTree->pLeft);
	return pTree;
}
PtrTreeNode newTreeNode(int val) {//创建一个data=val,孩子均为NULL的新节点
	
	PtrSearchTree pTree = (PtrSearchTree)malloc(sizeof(TreeNode));
	if (pTree == NULL) {
		printf("pTree分配内存失败!\n");
	}
	else {
		pTree->data = val;
		pTree->pLeft = NULL;
		pTree->pRight = NULL;
	}

	return pTree;
}
PtrSearchTree Delete(int val, PtrSearchTree pTree) {//删除val,返回删除后的新树的根(全看成在根节点(第一次输入)进行操作)
	if (pTree == NULL) {
		printf("树中没有要删除的元素!\n");
		return NULL;
	}
	else if (val > pTree->data)
		pTree->pRight = Delete(val, pTree->pRight);//到右子树中删除,返回右子树的根
	else if (val < pTree->data)
		pTree->pLeft = Delete(val, pTree->pLeft);到左子树中删除,返回左子树的根
	else {//val == pTree->data,看有几个子节点
		if (pTree->pLeft != NULL && pTree->pRight != NULL) {//两个子节点
			//删除方法:我变成你(右子树中的最小值),再杀了你,等于我杀了我自己
			PtrTreeNode pTemp = findMinNode(pTree->pRight);
			pTree->data = pTemp->data;
			pTree->pRight = Delete(pTemp->data, pTree->pRight);
		}
		else {//一个或0个节点
			//删除方法:直接删除
			PtrTreeNode pTemp = pTree;
			if (pTree->pLeft == NULL)
				pTree = pTree->pRight;
			else if (pTree->pRight == NULL)
				pTree = pTree->pLeft;
			free(pTemp);
		}
	}

	return pTree;
}
void inorderTraversal(PtrSearchTree pTree) {//中序遍历

	if (pTree == NULL) {
		printf("树为空!\n");
		exit(-1);
	}
	if (pTree->pLeft != NULL)
		inorderTraversal(pTree->pLeft);
	printf("%d ", pTree->data);
	if (pTree->pRight != NULL)
		inorderTraversal(pTree->pRight);

	return;
}
void showTree(PtrSearchTree pTree) {

	if (pTree == NULL) {
		printf("树为空!\n");
		return;
	}
	printf("中序遍历该树:");
	inorderTraversal(pTree);
	printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、二叉树(二) 1. 写算法 (1)二叉树的直径定义为从根结点至叶子的最大路径长度。编写算法,求二叉树(二叉链表)的直径。 (2)已知二叉树(二叉链表)根结点指针bt,树中两个结点的指针p、q。编写算法求距离结点*p和*q最近的公共祖先的地址。 (3)已知二叉树(二叉链表)根结点指针bt,利用二叉树叶子结点的rchild指针域将所有叶子结点从左向右连接成一个单向链表。算法返回单向链表头结点指针(即最左边第1个叶子结点的地址)。 2. 编程题 (1) 从键盘输入一个字符串(要求字符串中无重复字符),将串中字符当做完全二叉树的顺序存储结构,建立对应的完全二叉树的二叉链表存储结构,输出先、中、后序遍历结果。 (2) 用先序遍历法建立二叉树二叉链表存储结构(结点数据域类型为char,输入字符序列用字符'#'表示NULL),实现中序线索化,并用非递归算法输出中序遍历结果的正序和逆序序列。 二、图 1. 已知某无向图如下图所示。画出该图的多重邻接表存储结构示意图。根据该存储结构,写出从顶点v0出发,深度和宽度优先遍历顶点访问次序。 2.写一个算法,判断无向图是否有环。算法提要:深度优先遍历过程中,访问某顶点后,该顶点的邻接点中有已访问的顶点且该已访问邻接点不是该顶点的上一级递归出发顶点(即存在回边),则有环。 3.编程题: 建立无向图邻接表存储结构,输出深度和宽度优先遍历顶点访问次序。 4.编程题:建立AOE网络存储结构,计算并输出ve[]和vl[]。 5.选作题*:算法设计-已知AOE网络的邻接表存储结构G,ve[]和vl[]值已全部求取,写出算法,输出所有关键路径。要求每条关键路径用源点至汇点的顶点序列(拓扑有序)表示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值