顺序查找 折半查找 二叉排序树

1.顺序查找,折半查找,二叉排序树操作定义

SeqSearch.h

#include<stdio.h>
#define ARRAYLEN 8

int source[]={69, 65, 90, 37, 92, 6, 28, 54};		//静态查找表
int source1[ARRAYLEN + 1]={69, 65, 90, 37, 92, 6, 28, 54};		//改进顺序查找算法使用的静态查找表
int source2[]={6, 12, 28, 37, 54, 65, 69, 83};					//折半查找算法使用的静态查找表
//int source3[12]={54, 90, 6, 69, 12, 37, 92, 28, 65, 83, 91, 94};
int source3[2]={92, 12};

/*******************顺序查找start*********************/
/*
	优点:对静态查找表数据顺序没有要求;若需创建动态查找表,可方便地将查找不成功数据添加到表的末尾
	缺点:速度慢,复杂度为O(n)
*/
//功能:顺序查找
int SeqSearch(int s[], int n, int key){
	int i;
	for(i=0; i<n && s[i]!=key; i++)	//循环查找关键字
		;
	if(i<n)
		return i;
	else
		return -1;
}

//功能:改进的顺序查找方法(在创建静态查找表时,在该表的末端增加一个空的单元,用来保存查找的关键字;保证查找表中总能找到关键字)
int SeqSearch1(int s[], int n, int key){
	int i;
	for(i=0; s[i]!=key; i++)		//减少比较次数
		;
	if(i<n)
		return i;
	else
		return -1;
}

/*******************顺序查找end*********************/


/*******************折半查找start*********************/
/*
	优点:查找速度快O(nlogn)
	缺点:1)静态查找表必须是有序的,
	      2)将查找不成功关键字数据添加到查找表中,需要大量的移动操作
*/
//功能:顺序查找
int BinarySearch(int s[], int n, int key){
	int left, mid, right;
	left = 0;
	right = n-1;
	
	while(left <= right){
		mid = (left + right)/2;
		if(s[mid] == key)
			return mid;
		else if(s[mid] > key)
			right = mid - 1;
		else
			left = mid + 1;
	}
	return -1;
}

/*******************折半查找end*********************/

/*******************二叉排序树查找start*********************/
/*
	优点:查找速度快O(nlogn)
	缺点:1)静态查找表必须是有序的,
	      2)将查找不成功关键字数据添加到查找表中,需要大量的移动操作
*/
//功能:定义二叉树结构
typedef struct bst{
	int data;
	struct bst *left;
	struct bst *right;
}BSTree;

//功能:在二叉排序树中插入关键字key,插入后一定是一个叶子节点
//假设不会出现相同的数据
void InsertBSTree(BSTree *bt, int key){
	BSTree *p, *head, *parent;
	if(!(p=(BSTree *)malloc(sizeof(BSTree)))){
		printf("申请内存出错!\n");
		exit(0);
	}
	//初始化申请的内存空间
	p->data = key;
	p->left = NULL;
	p->right = NULL;

	//查找需要添加的父节点
	head = bt;
	while(head){
		parent = head;  //退出循环时head==NULL,所以用parent,指向前一个节点
		if(head->data > key)
			head = head->left;
		else
			head = head->right;
	}
	//判断添加到左子树还是右子树上
	if(key < parent->data)
		parent->left = p;
	else 
		parent->right = p;
}

//功能:创建二叉排序树
void CreateBST(BSTree *t, int data[], int n){
	int i;
	t->data = data[0];				//初始化根节点
	t->left = t->right = NULL;
	for(i=1; i<n; i++)
		InsertBSTree(t, data[i]);
}

//功能:中序遍历二叉排序树
void BST_LDR(BSTree *t){
	if(t){
		BST_LDR(t->left);
		printf("%d ", t->data);
		BST_LDR(t->right);
	}
}

//功能:二叉排序树的查找
BSTree *searchBST(BSTree *t, int key){
	if(!t || t->data == key)
		return t;
	else if(t->data > key)
		return (searchBST(t->left, key));
	else
		return (searchBST(t->right, key));
}

//功能:删除二叉排序树中的节点
void BST_Delete(BSTree *t, int key){
	BSTree *p, *parent, *ll, *l;
	int child=0;	//0表示左子树,1表示右子树
	int flag = 1;
	if(!t)		//二叉排序树为空
		return;
	p = t;
	parent = p;
	while(flag){
		//p节点数据等于关键字
		if(p->data == key){
			//p节点为叶节点(左右子树均为空)
			if(!p->left && !p->right){
				if(p==t)			//被删除的是根节点
					free(p);
				else if(child==0){
					parent->left = NULL;
					free(p);
				}
				else{
					parent->right = NULL;
					free(p);
				}
				p = NULL;
				flag = 0;
			}
			//p节点左子树为空,右子树不空
			else if(!p->left){
				if(child==0)
					parent->left = p->right;
				else
					parent->right = p->right;
				free(p);
				p = NULL;
				flag = 0;
			}
			//p节点右子树为空,左子树不空
			else if(!p->right){
				if(child==0)
					parent->left = p->left;
				else
					parent->right = p->left;
				free(p);
				p = NULL;
				flag = 0;
			}
			//p节点为分支节点(左右子树均不空)
			else{
				ll=p;
				l=p->right;
				if(l->left){
					while(l->left){
						ll = l;
						l = l->left;
					}
                                        p->data = l->data;
					ll->left = NULL;
					
				}
				else{
					p->data = l->data;
					p->right = l->right;
				}
				free(l);
                                flag = 0;
			}
		}
		//p节点数据大于关键字
		else if(p->data > key){
			child = 0;
			parent = p;
			p = p->left;
		}
		//p节点数据小于关键字
		else{
			child = 1;
			parent = p;
			p = p->right;
		}
	}
}
/*******************二叉排序树查找end*********************/


2. 测试查找操作

BSTreeTest.cpp

#include<stdio.h>
#include<stdlib.h>

#include"SeqSearch.h"

int main(){
	int key, i, pos;
	BSTree bst, *pos1;
	int select;
	int data;

	do{
		printf("---------------------------\n");
		printf("1.顺序查找算法           2.改进后的顺序查找算法\n");
		printf("3.折半查找算法           4.创建二叉排序树\n");
		printf("5.遍历二叉排序树         6.二叉排序树查找算法\n");
		printf("7.删除二叉排序树的某个节点\n");
		printf("0.退出\n");
		printf("请选择执行的操作序号:");
		//select = getch();
		fflush(stdin);
		scanf("%d", &select);
		switch(select){
			case 1:
				printf("请输入查找关键字:");
				fflush(stdin);
				scanf("%d", &key);
				//调用顺序查找算法
				pos = SeqSearch(source, ARRAYLEN, key);
				if(pos>=0)
					printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
				else
					printf("查找失败。\n");
				break;
			case 2:
				printf("请输入查找关键字:");
				fflush(stdin);
				scanf("%d", &key);
				source1[ARRAYLEN]=key;		//将查找关键字放入最后一个位置
				//调用改进后的顺序查找算法
				pos = SeqSearch1(source1, ARRAYLEN, key);
				if(pos>=0)
					printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
				else
					printf("查找失败。\n");
				break;
			case 3:
				printf("请输入查找关键字:");
				fflush(stdin);
				scanf("%d", &key);
				//调用折半查找算法
				pos = BinarySearch(source1, ARRAYLEN, key);
				if(pos>=0)
					printf("查找成功,该关键字位于数组的第%d个位置。\n", pos+1);
				else
					printf("查找失败。\n");
				break;
			case 4:
				CreateBST(&bst, source3, 2);		//创建二叉排序树
				break;
			case 5:
				printf("二叉排序树遍历结果:");
				BST_LDR(&bst);					//遍历二叉排序树
				printf("\n");
				break;
			case 6:
				printf("请输入查找关键字:");
				fflush(stdin);
				scanf("%d", &key);
				pos1 = searchBST(&bst, key);
				printf("原数据为:");
				for(i=0; i<2; i++)
					printf("%d ", source3[i]);
				printf("\n");
				if(pos1)
					printf("查找成功,该节点的地址为:%x\n", pos1);
				else
					printf("查找失败。\n");
				break;
			case 7:
				printf("请输入要删除的关键字:");
				fflush(stdin);
				scanf("%d", &key);
				BST_Delete(&bst, key);
				break;
		}
	}while(select != 0);
	system("pause");
	return 0;
}



相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页