【数据结构复习】顺序查找 二分查找 二叉排序树

顺序查找

一般线性表顺序查找

typedef struct{
	ElemType elem[10];
	int TableLen;
}SSTable;
int Search_Seq(SSTable ST,ElemType key){
	ST.elem[0]=key;//哨兵引入,不用判断查找是否越界
	for(int i=ST.TableLen;ST.elem[i]!=key;i--);
	return i;//输出0说明没有找到
}

顺序查找平均长度 A S L 成功 = Σ i − 1 n P i ( n − i + 1 ) = n + 1 2 ASL_{成功}=\Sigma_{i-1}^nP_i(n-i+1)=\frac{n+1}{2} ASL成功=Σi1nPi(ni+1)=2n+1

有序表顺序查找

从前往后查,如果第i个元素小于key,第i+1个元素大于key,则查找失败直接退出。
A S L 不成功 = Σ j = 1 n q j ( l j − 1 ) = 1 + 2 + ⋅ ⋅ ⋅ + n + n n + 1 = n 2 + n n + 1 ASL_{不成功}=\Sigma_{j=1}^nq_j(l_j-1)=\frac{1+2+···+n+n}{n+1}=\frac{n}{2}+\frac{n}{n+1} ASL不成功=Σj=1nqj(lj1)=n+11+2+⋅⋅⋅+n+n=2n+n+1n

二分查找

仅适用于有序顺序表

int Binary_Search(SSTable L,ElemType key){
	int low=0,high=L.TableLen-1,mid;
	while(low<=high){
		mid=(low+high)/2;
		if(L.elem[mid]==key) return mid;
		if(L.elem[mid]>key) high=mid-1;
		else low=mid+1;
	}
	return -1;
}

获得的判定树是一棵平衡二叉树
性质1 h = ⌈ l o g 2 ( n + 1 ) ⌉ h=\lceil log_2(n+1)\rceil h=log2(n+1)⌉
性质2 若查找表有 n n n个关键字,则有 n + 1 n+1 n+1个失败关键字
性质3 如何判断一棵树是不是折半排序的判定树:如果是下取整,每一个节点的左子树结点数都小于等于右子树;如果是上取整,每一个节点的右子树节点数都小于等于左子树
等概率情况下,查找成功平均长度
A S L = 1 n ∑ i = 1 n l i = 1 n ∑ i = 1 n ( 层数 × 每层非空结点数 ) ASL=\frac{1}{n}\sum_{i=1}^{n}l_i=\frac{1}{n}\sum_{i=1}^n(层数\times 每层非空结点数) ASL=n1i=1nli=n1i=1n(层数×每层非空结点数)

二叉排序树

构造一棵二叉排序树的目的并不是为了排序,而是为了提高查找、插入和删除关键字的速度

性质

1)若左子树非空,则左子树上所有结点的值均小于根节点的值
2)若右子树非空,则右子树上所有结点的值均大于根节点的值
3)左、右子树也分别是一棵二叉排序树

二叉排序树的查找

从根节点开始。
若二叉排序树非空,则将key与根节点比较,若相等则查找成功,若小于根节点关键字,在左子树查找;若大于根节点关键字,在右子树查找。

BSTNode *BST_Search(BiTree T,ElemType key){
	while(T!=NULL&&key!=T.data){
		if(key<T->data) T=T->lchild;
		else T=T->rchild;
	}
	return T;
}

二叉排序树的插入

int BST_Insert(BiTree* T,ElemType k){
	if((*T)==NULL){
		(*T)=(BiTNode*)malloc(sizeof(BiTNode));
		(*T)->data=k;
		(*T)->lchild=NULL;
		(*T)->rchild=NULL;
		return 1;
	}
	if((*T)->data==k) return 0;//该数据已经存在,无法插入
	if(k<(*T)->data) return BST_Insert(&((*T)->lchild),k);
	return BST_Insert(&((*T)->rchild),k);
}

二叉排序树的构造

void Creat_BST(BiTree* T,ElemType data[],int n){
	(*T)=NULL;
	int i=0;
	while(i<n){
		BST_Insert(T,data[i]);
		i++;
	}
}

二叉排序树的删除

1)叶结点-直接删除
2)该结点只有一棵左子树或者右子树,直接让子树替代该结点位置
3)若结点有左右两棵子树,则让z的直接后继(或直接前驱)替代z,然后删除这个直接前驱(或直接后继),这样就转化成了1)或2)

void Delete_BST(ElemType key){
	BiTree* T=&first;
	while((*T)!=NULL&&key!=(*T)->data){
		if(key<(*T)->data) T=&((*T)->lchild);
		else T=&((*T)->rchild);
	}
	
	if((*T)==NULL) return;
	if((*T)->lchild==NULL&&(*T)->rchild==NULL){
		(*T)=NULL;//叶子结点
		return;
	}
	if((*T)->lchild==NULL){
		(*T)=(*T)->rchild;
		return;
	}
	if((*T)->rchild==NULL){
		(*T)=(*T)->lchild;
		return;
	}//两种只有一个子树的情况
	
	BiTree* s;
	s=&((*T)->lchild);
	while((*s)->rchild!=NULL) s=&((*s)->rchild);
	(*T)->data=(*s)->data;
	(*s)=NULL;
}

完整代码(已经调通)(C语言)

#include <stdio.h>
#define ElemType int
typedef struct BiTNode{
	ElemType data;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
BiTree first;
void Creat_BST(BiTree* T,ElemType data[],int n){
	(*T)=NULL;
	int i=0;
	while(i<n){
		BST_Insert(T,data[i]);
		i++;
	}
}
BiTree BST_Search(BiTree T,ElemType key){
	while(T!=NULL&&key!=T->data){
		if(key<T->data) T=T->lchild;
		else T=T->rchild;
	}
	return T;
}

int BST_Insert(BiTree* T,ElemType k){
	if((*T)==NULL){
		(*T)=(BiTNode*)malloc(sizeof(BiTNode));
		(*T)->data=k;
		(*T)->lchild=NULL;
		(*T)->rchild=NULL;
		return 1;
	}
	if((*T)->data==k) return 0;//该数据已经存在,无法插入
	if(k<(*T)->data) return BST_Insert(&((*T)->lchild),k);
	return BST_Insert(&((*T)->rchild),k);
}
void Delete_BST(ElemType key){
	BiTree* T=&first;
	while((*T)!=NULL&&key!=(*T)->data){
		if(key<(*T)->data) T=&((*T)->lchild);
		else T=&((*T)->rchild);
	}
	
	if((*T)==NULL) return;
	if((*T)->lchild==NULL&&(*T)->rchild==NULL){
		(*T)=NULL;//叶子结点
		return;
	}
	if((*T)->lchild==NULL){
		(*T)=(*T)->rchild;
		return;
	}
	if((*T)->rchild==NULL){
		(*T)=(*T)->lchild;
		return;
	}//两种只有一个子树的情况
	
	BiTree* s;
	s=&((*T)->lchild);
	while((*s)->rchild!=NULL) s=&((*s)->rchild);
	(*T)->data=(*s)->data;
	(*s)=NULL;
}

int data[10]={10,9,2,3,7,8};
int main(){
	first=NULL;
	int i=0,n=5;
	Creat_BST(&first,data,5);
	BiTree ans=BST_Search(first,3);
	Delete_BST(2);
	ans=BST_Search(first,3);
	if(ans!=NULL) printf("%d",ans->data);
	else printf("no");
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值