PAT刷题模板——BST和AVL树

BST模板

// BST 二叉查询树
typedef struct TNode {
	int val;
	struct TNode *left, *right;
} TNode;

// 插入结点
TNode* insert(TNode *root, int val){
	if(root == NULL){
		root = new TNode();
		root->val = val;
		root->left = root->right = NULL;
	} else if(val < root->val){
		root->left = insert(root->left, val);
	} else 
		root->right = insert(root->right, val);
	return root;
}

// 建立树
TNode* createBST(int pre[], int n){
	TNode* root = NULL;
	for(int i = 0; i < n; i++){
		root = insert(root, pre[i]);
	}
	return root;
}

// 查询返回结点指针
TNode* search(TNode* root, int val){
	if(root == NULL) return root;
	else if(val < root->val) return search(root->left, val);
	else if(val > root->val) return search(root->right, val);
	else return root;
}

TNode* deleteNode(TNode* root, int val){
	if(root == NULL) // 查找删除失败
		return root;
	else if(val < root->val)
		root->left = deleteNode(root->left, val);
	else if(val > root->val)
		root->right = deleteNode(root->right, val);
	else {
		if(root->left == NULL && root->right == NULL)
			root = NULL;
		else if(root->left != NULL){
			TNode* pre = root->left;
			while(pre->right != NULL)
				pre = pre->right;
			root->data = pre->data;
			root->left = deleteNode(root->left, pre->data);
		} else {
			TNode* next = root->right;
			while(next->left != NULL)
				next = next->left;
			root->data = next->data;
			root->right = deleteNode(root->right, next->data);
		}
	}
	return root;
}

// 清空树
void destroyBST(TNode* root){
	if(root == NULL) return;
	destroyBST(root->left);
	destroyBST(root->right);
	free(root);
	// delete root;
}

AVL模板

// 节点
typedef struct TNode {
	int data;
	struct TNode *left, *right;
} TNode;

// 左旋操作
TNode* rotateLeft(TNode *root){
	TNode *t = root -> right;
	root -> right = t -> left;
	t -> left = root;
	return t;
}

// 右旋操作
TNode* rotateRight(TNode *root){
	TNode *t = root -> left;
	root -> left = t -> right;
	t->right = root;
	return t;
}

// 左右旋操作
TNode* rotateLeftRight(TNode *root){
	root->left = rotateLeft(root->left);
	return rotateRight(root);
}

// 右左旋操作
TNode* rotateRightLeft(TNode *root){
	root->right = rotateRight(root->right);
	return rotateLeft(root);
}

// 求二叉树高度
int getHeight(TNode *root){
	if(root == NULL) return 0;
	return max(getHeight(root->left), getHeight(root->right)) + 1;
}

// 插入结点
TNode* insert(TNode *root, int data){
	// 递归出口 叶节点
	if(root == NULL){
		root = new TNode();
		root->data = data;
		root->left = root->right = NULL;
	} else if(data < root->data){
		// 左插
		root->left = insert(root->left, data);
		if(getHeight(root->left) - getHeight(root->right) == 2){
			// 插入后失衡了
			if(data < root->left->data) // LL情况
				root = rotateRight(root);
			else //LR的情况
				root = rotateLeftRight(root);
		}
	} else {
		root->right = insert(root->right, data);
        if(getHeight(root->left) - getHeight(root->right) == -2){
            if(data > root->right->data)// RR 情况
			    root = rotateLeft(root);
		    else // RL情况
			    root = rotateRightLeft(root);
        }
	}
	return root;
}

TNode* createAVL(int A[], int n){
	TNode* root = NULL;
	for(int i = 0; i < n; i++){
		root = insert(root, A[i]);
	}
	return root;
}	

// 查找 并返回指针
TNode* search(TNode *root, int data){
	if(root == NULL) return NULL; // 查找失败
	else if(root->data == data) return root;
	else if(data < root->data) return search(root->left, data);
	else return search(root->right, data);
}

// 删除操作
// 找到前驱结点
TNode* findMax(TNode *root){
	while(root->right != NULL){
		root = root->right;
	}
	return root;
}

// 找到后继结点
TNode* findMin(TNode* root){
	while(root->left != NULL){
		root = root->left;
	}
	return root;
}

// 删除操作
TNode* deleteNode(TNode *root, int data){
	if(root == NULL) return root; // 查找失败 无对应的结点
	else if(data < root->data) {
		root->left = deleteNode(root->left, data);
	} else if(data > root->data) {
		root->right = deleteNode(root->right, data);
	} else {
		// data == root->data;
		if(root->left == NULL && root->right == NULL){
			root = NULL;
		} else if(root->left != NULL) {
			TNode* pre = findMax(root->left); // 找到左子树最大的结点 即root中序的先驱结点
			root->data = pre->data;
			root->left = deleteNode(root->left, pre->data);
		} else {
			TNode* next = findMin(root->right);
			root->data = next->data;
			root->right = deleteNode(root->right, next->data);
		}
	}
	if(root == NULL) return root;
	
	// balance的过程
	int heightSub = getHeight(root->left) - getHeight(root->right);
	if (heightSub == 2) {
		/*
		   左树比右树来的高了 
		   说明删除了右树中的结点 
		   等价于在左树增加了结点
		*/
		TNode *left = root->left;
		if(getHeight(left->left) >= getHeight(left->right)){
			// 左子树的左子树比较高 相当于在左子树的左子树里插入了结点
			root = rotateRight(root);
		} else {
			root = rotateLeftRight(root);
		}
	} else if(heightSub = -2) {
		/*
			右树比左树来的高
			说明删除了左树的结点
			那么相当于增加了右树的结点
		*/
		TNode *right = root->right;
		if(getHeight(right->right) >= getHeight(right->left)){
			// 右树的右子树比较高 相当于在右树的右子树加入了一个结点
			root = rotateLeft(root);
		} else {
			root = rotateRightLeft(root);
		}
	}
	return root;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值