数据结构-二叉排序树操作实践

数据结构-二叉排序树操作实践

编写函数,建立有序表,利用二叉排序树的插入算法建立二叉排序树

#include<iostream>
#include<malloc.h>
using namespace std;
#define MAXSIZE 50
// 定义二叉树的结点
typedef struct BiTNode {
   
	int data;
	struct BiTNode* lChild, * rChild;
}BiTNode, *BiTree;


/** * 在二叉排序树T中插入一个关键字为k的结点 * @param T 二叉排序树T * @param k 要插入的关键字k * @return 成功返回真,否则为假 */
bool BST_Insert(BiTree& T, int k) {
   
	if (T == NULL) {
     // 原数为空,新插入的记录为根结点
		T = (BiTree)malloc(sizeof(BiTNode));
		if (T) {
   
			T->data = k;
			T->lChild = T->rChild = NULL;
			return true;  // 成功
		}
	}
	else if (k == T->data)  // 树中存在相同关键字的结点
		return false;
	else if (k < T->data)  // 插入T的左子树
		return BST_Insert(T->lChild, k);
	else   // 插入T的右子树
		return BST_Insert(T->rChild, k);
}

/** * 用关键字数组构造二叉排序树 * @param T 二叉排序树T * @param keys 关键字数组 * @param n 关键字数组的元素个数 */
void Creat_BST(BiTree& T, int keys[], int n) {
   
	T = NULL;  // 初始化为空树
	int i = 0;
	while (i < n) {
     // 将为每个元素依次插入
		BST_Insert(T, keys[i]);
		i++;
	}
}

/** * 先序遍历二叉排序树 * @param T 二叉排序树T */
void PreOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		cout << T->data << " ";
		PreOrder_BST(T->lChild);
		PreOrder_BST(T->rChild);
	}
}

/** * 中序遍历二叉排序树 * @param T 二叉排序树T */
void InOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		InOrder_BST(T->lChild);
		cout << T->data << " ";
		InOrder_BST(T->rChild);
	}
}

/** * 后序遍历二叉排序树 * @param T 二叉排序树T */
void PostOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		PostOrder_BST(T->lChild);
		PostOrder_BST(T->rChild);
		cout << T->data << " ";
	}
}

int main() {
   
	int n;
	cin >> n;

	int keys[MAXSIZE];
	for (int i = 0; i < n; i++)
		cin >> keys[i];

	BiTree T;
	Creat_BST(T, keys, n);

	cout << "先序遍历:";
	PreOrder_BST(T);
	cout << endl;
	
	cout << "中序遍历:";
	InOrder_BST(T);
	cout << endl;

	cout << "后序遍历:";
	PostOrder_BST(T);
	cout << endl;

	return 0;
}

注:

  • 二叉排序树中默认没有相同的元素
  • 输入的顺序是随意的,自己可以手动的根据输入的顺序构造二叉排序树,再对该二叉排序树进行先、中、后序遍历,跟输出的遍历结果对照,即可判断程序所构造的二叉排序树是否正确。

在以上二叉排序树中删除某一指定关键字元素

/** * 从二叉排序树中删除结点p,并重接它的左或右子树 * @param p 要删除的结点 * @return 成功为真 */
bool Delete(BiTree& p) {
   
	BiTree q, s;
	if (!p->rChild) {
     // 右子树为空,则只需要重接它的左子树
		q = p;
		p = p->lChild;
		free(q);
	}
	else if (!p->lChild) {
     // 左子树为空,则只需要重接它的右子树
		q = p;
		p = p->rChild;
		free(q);
	}
	else {
     // 左右子树均不为空
		q = p;
		s = p->lChild;
		while (s->rChild) {
     // 转左,然后向右到尽头
			q = s;
			s = s->rChild;
		}
		p->data = s->data;  // s指向被删结点的前驱
		if (q != p)  // 重接*q的右子树
			q->rChild = s->lChild;
		else  // 重接*q的左子树
			q->lChild = s->rChild;
		free(s);
	}
	return true;
}
/** * 在二叉排序树中删除关键字等于key的结点 * @param T 二叉排序树T * @param key 要删除的关键字元素 * @return 成功返回真,否则返回假 */
bool DeleteBST(BiTree& T, int key) {
   
	if (!T)  // T为空
		return false;
	else
	{
   
		if (key == T->data)  //找到关键字等于key的数据元素
			return Delete(T);
		else if (key < T->data)
			return DeleteBST(T->lChild, key);
		else
			return DeleteBST(T->rChild, key);
	}
}
int key;
cin >> key;
DeleteBST(T, key);
cout << "------删除" << key << "------" << endl;

cout << "先序遍历:";
PreOrder_BST(T);
cout << endl;

cout << "中序遍历:";
InOrder_BST(T);
cout << endl;

cout << "后序遍历:";
PostOrder_BST(T);
cout << endl;

注:

  • 二叉排序树中默认没有相同的元素
  • 输入的顺序是随意的,自己可以手动的根据输入的顺序构造二叉排序树,再对该二叉排序树进行先、中、后序遍历,跟输出的遍历结果对照,即可判断程序所构造的二叉排序树是否正确。
  • 在二叉排序树中删除元素是一件比较麻烦的事,根据不同的情况,在删除后要对树进行不同的调整。

采用折半查找实现某一已知的关键字的查找(采用顺序表存储结构)

这里继续基于上面的程序来写,显然,二叉排序树的中序遍历即为一个递增的顺序。我们利用中序遍历来构造一个顺序表,再进行折半查找操作

int SeqT[MAXSIZE];  // 定义一个顺序表,用于折半查找
int t=0;
/** * 中序遍历二叉排序树 * @param T 二叉排序树T */
void InOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		InOrder_BST(T->lChild);
		cout << T->data << " ";
		SeqT[t++] = T->data;  // 按中序遍历的方式遍历二叉排序树即可得到一组有序的数
		InOrder_BST(T->rChild);
	}
}

/** * 折半查找 * @param SeqT 有序表 * @param n 有序表中元素个数 * @param key 待查找的关键字 * @return 该关键字在表中的位置(第几个),否则返回0 */
int Search_Bin(int SeqT[], int n, int key) {
   
	int low = 0;
	int high = n - 1;
	int mid;
	while (low <= high) {
   
		mid = (low + high) / 2;
		if (key == SeqT[mid])  // 找到待查元素
			return mid + 1;
		else if (key < SeqT[mid])  // 继续在前半区间查找
			high = mid - 1;
		else  // 继续在后半区间查找
			low = mid + 1;
	}
	return 0;  // 有序表中不存在待查元素
}
int key2;
cin >> key2;
cout << key2 << "在表中第" << Search_Bin(SeqT, n, key2) << "个位置";

完成程序代码

#include<iostream>
#include<malloc.h>
using namespace std;
#define MAXSIZE 50
int SeqT[MAXSIZE];  // 定义一个顺序表,用于折半查找
int t=0;

// 定义二叉树的结点
typedef struct BiTNode {
   
	int data;
	struct BiTNode* lChild, * rChild;
}BiTNode, *BiTree;


/** * 在二叉排序树T中插入一个关键字为k的结点 * @param T 二叉排序树T * @param k 要插入的关键字k * @return 成功返回真,否则为假 */
bool BST_Insert(BiTree& T, int k) {
   
	if (T == NULL) {
     // 原数为空,新插入的记录为根结点
		T = (BiTree)malloc(sizeof(BiTNode));
		if (T) {
   
			T->data = k;
			T->lChild = T->rChild = NULL;
			return true;  // 成功
		}
	}
	else if (k == T->data)  // 树中存在相同关键字的结点
		return false;
	else if (k < T->data)  // 插入T的左子树
		return BST_Insert(T->lChild, k);
	else   // 插入T的右子树
		return BST_Insert(T->rChild, k);
}

/** * 用关键字数组构造二叉排序树 * @param T 二叉排序树T * @param keys 关键字数组 * @param n 关键字数组的元素个数 */
void Creat_BST(BiTree& T, int keys[], int n) {
   
	T = NULL;  // 初始化为空树
	int i = 0;
	while (i < n) {
     // 将为每个元素依次插入
		BST_Insert(T, keys[i]);
		i++;
	}
}

/** * 先序遍历二叉排序树 * @param T 二叉排序树T */
void PreOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		cout << T->data << " ";
		PreOrder_BST(T->lChild);
		PreOrder_BST(T->rChild);
	}
}

/** * 中序遍历二叉排序树 * @param T 二叉排序树T */
void InOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		InOrder_BST(T->lChild);
		cout << T->data << " ";
		SeqT[t++] = T->data;  // 按中序遍历的方式遍历二叉排序树即可得到一组有序的数
		InOrder_BST(T->rChild);
	}
}

/** * 后序遍历二叉排序树 * @param T 二叉排序树T */
void PostOrder_BST(BiTree T) {
   
	if (T != NULL) {
   
		PostOrder_BST(T->lChild);
		PostOrder_BST(T->rChild);
		cout << T->data << " ";
	}
}


/** * 从二叉排序树中删除结点p,并重接它的左或右子树 * @param p 要删除的结点 * @return 成功为真 */
bool Delete(BiTree& p) {
   
	BiTree q, s;
	if (!p->rChild) {
     // 右子树为空,则只需要重接它的左子树
		q = p;
		p = p->lChild;
		free(q);
	}
	else if (!p->lChild) {
     // 左子树为空,则只需要重接它的右子树
		q = p;
		p = p->rChild;
		free(q);
	}
	else {
     // 左右子树均不为空
		q = p;
		s = p->lChild;
		while (s->rChild) {
     // 转左,然后向右到尽头
			q = s;
			s = s->rChild;
		}
		p->data = s->data;  // s指向被删结点的前驱
		if (q != p)  // 重接*q的右子树
			q->rChild = s->lChild;
		else  // 重接*q的左子树
			q->lChild = s->rChild;
		free(s);
	}
	return true;
}
/** * 在二叉排序树中删除关键字等于key的结点 * @param T 二叉排序树T * @param key 要删除的关键字元素 * @return 成功返回真,否则返回假 */
bool DeleteBST(BiTree& T, int key) {
   
	if (!T)  // T为空
		return false;
	else
	{
   
		if (key == T->data)  //找到关键字等于key的数据元素
			return Delete(T);
		else if (key < T->data)
			return DeleteBST(T->lChild, key);
		else
			return DeleteBST(T->rChild, key);
	}
}

/** * 折半查找 * @param SeqT 有序表 * @param n 有序表中元素个数 * @param key 待查找的关键字 * @return 该关键字在表中的位置(第几个),否则返回0 */
int Search_Bin(int SeqT[], int n, int key) {
   
	int low = 0;
	int high = n - 1;
	int mid;
	while (low <= high) {
   
		mid = (low + high) / 2;
		if (key == SeqT[mid])  // 找到待查元素
			return mid + 1;
		else if (key < SeqT[mid])  // 继续在前半区间查找
			high = mid - 1;
		else  // 继续在后半区间查找
			low = mid + 1;
	}
	return 0;  // 有序表中不存在待查元素
}


int main() {
   
	int n;
	cin >> n;

	int keys[MAXSIZE];
	for (int i = 0; i < n; i++)
		cin >> keys[i];

	BiTree T;
	Creat_BST(T, keys, n);

	cout << "先序遍历:";
	PreOrder_BST(T);
	cout << endl;
	
	cout << "中序遍历:";
	InOrder_BST(T);
	cout << endl;

	cout << "后序遍历:";
	PostOrder_BST(T);
	cout << endl;

	int key;
	cin >> key;
	DeleteBST(T, key);
	cout << "------删除" << key << "------" << endl;

	cout << "先序遍历:";
	PreOrder_BST(T);
	cout << endl;

	cout << "中序遍历:";
	InOrder_BST(T);
	cout << endl;

	cout << "后序遍历:";
	PostOrder_BST(T);
	cout << endl;

	int key2;
	cin >> key2;
	cout << key2 << "在表中第" << Search_Bin(SeqT, n, key2) << "个位置";

	return 0;
}

创作不易,喜欢的话加个关注点个赞,谢谢谢谢谢!

全部评论

相关推荐

找不到工作死了算了:没事的,雨英,hr肯主动告知结果已经超越大部分hr了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务