BST-二叉查找树算导学习

本文详细介绍了C++二叉搜索树的基本概念、关键操作及其在实际编程中的应用,包括插入、中序遍历、查找、最小值、最大值、后继节点查找和删除节点等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

缺点还是有的-不平衡。

混了2天终于把代码写出来了,算法导论真是本好书啊


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct point {
	struct point *r,*l,*p;
	int key;
}point;
point *head,*p,node[100];//head:头指针
int num;
void init()
{
	head=p=NULL;
	num=0;
	memset(node,'\0',sizeof(node));
}
void insert(point* &head,int x)
{
	if(head==NULL)
	{
		node[num].key=x;
		node[num].p=p;
		head=&node[num++];
		return;
	}
	p=head;
	if(head->key>x)
		insert(head->l,x);
	else 
		insert(head->r,x);

}
//引用了以后可以再函数里面改变变量的值
//如下面的head不需要改变就没有引用
void inOrderTraver(point *head)
{
	if(head==NULL)
		return ;
	inOrderTraver(head->l);
	printf("%d ",head->key);
	inOrderTraver(head->r);
}
point* TreeSearch(point* &head,int k)//查找关键字为k的节点,返回指针
{
	if(head==NULL||k==head->key)
		return head;
	if(k<head->key)
		TreeSearch(head->l,k);
	else 
		TreeSearch(head->r,k);
}
point *TreeSearch2(point* head,int k)//查找,非递归版本,运行时间快,不至于栈溢出。
{
	point *tmp;
	tmp=head;
	while(tmp!=NULL&&k!=tmp->key)
	{
		if(k<tmp->key)
			tmp=tmp->l;
		else 
			tmp=tmp->r;
	}
	return tmp;
}
point* MINIMUM(point* head)
{
	point* tmp=head; 
	while(tmp->l!=NULL)
	{
		tmp=tmp->l;
	}
	return tmp;
}
point* MAXIMUM(point* head)
{
	point* tmp=head;
	while(tmp->r!=NULL)
		tmp=tmp->r;
	return tmp;
}
point* TreeSuccessor(point* tmp)//球后继。
{
	if(tmp->r !=NULL)
	{
		return MINIMUM(tmp->r);
	}
	point* y=tmp->p;
	while(y!=NULL&&tmp==y->r)
	{
		tmp=y;
		y=y->p;
	}
	return y;
}
point* deleteBST(point* &head,int k)
{
	point *z,*y,*x;
	z=TreeSearch2(head,k);
	if(z->l==NULL||z->r==NULL)//z 至少有一个为空
		y=z;
	else
		y=TreeSuccessor(z);//z有2个子女的话,y指向其前驱
	if(y->l!=NULL)  //y的左子树不空,x指向y的子女
		x=y->l;
	else 
		x=y->r;
	if(x!=NULL)//即y有子女
		x->p=y->p;
	if(y->p==NULL)//如果y是根节点
		head=x;
	else if(y==y->p->l)
		y->p->l=x;
	else y->p->r=x;
	if(y!=z)
		z->key=y->key;
	return y;
}
//1.该节点z没有子女,将它删除即可
//2.如果z有一个子女则删除z
//3.如果z有2个子女,则删除其后继y,它至多有一个子女,接着用y替换z.
int main()
{
	int x,k;
	point *tmp,*tt;
	init();
	while(~scanf("%d",&x))//构树,输入EOF结束
		insert(head,x);
	inOrderTraver(head);//中序输出
	putchar('\n');
	scanf("%d",&k);
	tmp=TreeSearch(head,k);
	if(tmp==NULL) printf("SEARCH FAILED  NO NUMBER!\n");//二叉树中无此数。
	else 
		printf("%d\n",tmp->key);
	inOrderTraver(head);//中序输出
	putchar('\n');
	tmp=MINIMUM(head);
	printf("MINIMUM: %d\n",tmp->key);
	tmp=MAXIMUM(head);
	printf("MAXIMUM: %d\n",tmp->key);
	scanf("%d",&k);
	tmp=TreeSearch(head,k);
	tt=TreeSuccessor(tmp);
	printf("%d后继:%d\n",k,tt->key);//查找后继
	scanf("%d",&k);//输入将被删除数
	tt=deleteBST(head,k);
	printf("%d\n",tt->key);
	inOrderTraver(head);//中序输出
	putchar('\n');
	return 0;
}



Practice 1 Date: Monday, March 18th, 2013 We highly encourage being environment friendly and trying all problems on your own. Implement exercise 2.3-7. Implement priority queue. Implement Quicksort and answer the following questions. (1) How many comparisons will Quicksort do on a list of n elements that all have the same value? (2) What are the maximum and minimum number of comparisons will Quicksort do on a list of n elements, give an instance for maximum and minimum case respectively. Give a divide and conquer algorithm for the following problem: you are given two sorted lists of size m and n, and are allowed unit time access to the ith element of each list. Give an O(lg m + lgn) time algorithm for computing the kth largest element in the union of the two lists. (For simplicity, you can assume that the elements of the two lists are distinct). Practice 2 Date: Monday, April 1st, 2013 We highly encourage being environment friendly and trying all problems on your own. Matrix-chain product. The following are some instances. Longest Common Subsequence (LCS). The following are some instances. X: xzyzzyx Y: zxyyzxz X:MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCALLAAQANKESSSESFISRLLAIVAD Y:MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCTLLAAQANKENSNESFISRLLAIVAG Longest Common Substring. The following are some instances. X: xzyzzyx Y: zxyyzxz X:MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCALLAAQANKESSSESFISRLLAIVAD Y:MAEEEVAKLEKHLMLLRQEYVKLQKKLAETEKRCTLLAAQANKENSNESFISRLLAIVAG Max Sum. The following is an instance. (-2,11,-4,13-5,-2) Shortest path in multistage graphs. Find the shortest path from 0 to 15 for the following graph.   A multistage graph is a graph (1) G=(V,E) with V partitioned into K >= 2 disjoint subsets such that if (a,b) is in E, then a is in Vi , and b is in Vi+1 for some subsets in the partition; and (2) | V1 | = | VK | = 1.     Practice 3 Date: Monday, April 15th, 2013 We highly encourage being environment friendly and trying all problems on your own. Knapsack Problem. There are 5 items that have a value and weight list below, the knapsack can contain at most 100 Lbs. Solve the problem both as fractional knapsack and 0/1 knapsack. A simple scheduling problem. We are given jobs j1, j2… jn, all with known running times t1, t2… tn, respectively. We have a single processor. What is the best way to schedule these jobs in order to minimize the average completion time. Assume that it is a nonpreemptive scheduling: once a job is started, it must run to completion. The following is an instance. (j1, j2, j3, j4) : (15,8,3,10) Single-source shortest paths. The following is the adjacency matrix, vertex A is the source.  A B C D E A -1 3 B 3 2 2 C D 1 5 E -3 All-pairs shortest paths. The adjacency matrix is as same as that of problem 3.(Use Floyd or Johnson’s algorithm)     Practice 4 Date: Monday, May 8th, 2013 We highly encourage being environment friendly and trying all problems on your own. 0/1 Knapsack Problem. There are 5 items that have a value and weight list below, the knapsack can contain at most 100 Lbs. Solve the problem using back-tracking algorithm and try to draw the tree generated. Solve the 8-Queen problem using back-tracking algorithm.    
### 二叉查找树在数据结构中的应用 二叉查找树(Binary Search Tree, BST)是一种重要的数据结构,其节点的值具有特定的顺序关系。对于每个节点,其左子树中所有节点的值均小于该节点的值,而右子树中所有节点的值均大于该节点的值[^1]。这种性质使得二叉查找树在插入、删除和查询操作上表现优异,尤其在动态数据集合中能够提供高效的性能。 #### 1. 插入操作 在二叉查找树中,插入新节点的过程是递归进行的。如果当前树为空,则直接创建一个新节点作为根节点;否则,根据新节点的值与当前节点的值比较,决定向左子树还是右子树继续插入。以下是插入操作的代码示例: ```c BiTreeNode* insertBiSortTree(BiTreeNode* root, int key) { if (!root) { root = (BiTreeNode*)malloc(sizeof(BiTreeNode)); root->data = key; root->left = NULL; root->right = NULL; } else { if (key > root->data) root->right = insertBiSortTree(root->right, key); else if (key < root->data) root->left = insertBiSortTree(root->left, key); } return root; } ``` 此代码片段展示了如何递归地将新节点插入到二叉查找树中[^2]。 #### 2. 创建二叉查找树 通过遍历一个无序数组并依次调用插入函数,可以构建一棵二叉查找树。以下代码展示了如何从数组中创建二叉查找树: ```c BiTreeNode* creatBiSortTree(int* arr, int n) { BiTreeNode* root = NULL; for (int i = 0; i < n; i++) { root = insertBiSortTree(root, arr[i]); } return root; } ``` 这段代码通过循环调用 `insertBiSortTree` 函数,逐步构建出完整的二叉查找树。 #### 3. 中序遍历 中序遍历是一种常见的树遍历方式,特别适用于二叉查找树。由于二叉查找树的性质,中序遍历的结果是一个升序排列的序列。以下是实现中序遍历的代码: ```c int* InOrder(BiTreeNode* root, int* arr, int &i) { if (!root) return NULL; InOrder(root->left, arr, i); arr[i++] = root->data; InOrder(root->right, arr, i); return arr; } ``` 此代码实现了对二叉查找树的中序遍历,并将结果存储到数组中[^3]。 #### 4. 判断数列是否升序 在某些场景下,需要验证中序遍历后的数列是否为升序。以下代码展示了如何判断一个数列是否为升序: ```c bool isOrder(int* arr, int n) { for (int j = 0; j < n - 1; j++) { if (arr[j + 1] < arr[j]) return false; } return true; } ``` 此函数通过遍历数组,逐一比较相邻元素来判断数列是否满足升序条件。 ### 总结 二叉查找树作为一种高效的数据结构,在动态数据集合的操作中表现出色。它支持快速的插入、删除和查询操作,并且通过中序遍历可以轻松获得有序序列。这些特性使其成为许多实际应用场景中的首选数据结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值