二叉排序树
//
// Created by lijing on 23-12-7.
//
#include "../../Define.h"
#define ENDFLAG -1
typedef int KeyType;
typedef int InfoType;
//- - - - -二叉排序树的二叉链表存储表示- - - - -
typedef struct
{
KeyType key; //关键字项
InfoType otherinfo; //其他数据项
}ElemType; //每个结点的数据域的类型
typedef struct BSTNode
{
ElemType data; //每个结点的数据域包括关键字项和其他数据项
struct BSTNode *lchild,*rchild; //左右孩子指针
}BSTNode,*BSTree;
void PritBST(BSTree T){
if(T){
PritBST(T->lchild);
cout<<T->data.key<<" ";
PritBST(T->rchild);
}
}
//二叉排序树
//- - - - -二叉排序树的查找- - - - -
/*二叉排序树可以看成是一个有序表,所以在二叉排序树上进行查找和折半查找类似,也是一个逐步缩小查找范围的过程。*/
BSTree SearchBST(BSTree T,KeyType key)
{ //在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素
//若查找成功,则返回指向该数据元素结点的指针,否则返回空指针
if((!T)||key==T->data.key) return T; //查找结束
else if(key < T->data.key) return SearchBST(T->lchild,key); //在左子树中继续查找
else return SearchBST(T->rchild,key); //在右子树中继续查找
}
//- - - - -二叉排序树的插入- - - - -
/**/
void InsertBST(BSTree &T, ElemType e)
{//当二叉排序树T中不存在关键字等于e.key的数据元素时,则插入该元素
if(!T)
{ //找到插入位置,递归结束
BSTNode* S=new BSTNode; //生成新结点*S
S->data=e; //新结点*S的数据域置为e
S->lchild=S->rchild=NULL; //新结点*S作为叶子结点
T=S; //把新结点*S链接到已找到的插入位置
}
else if(e.key<T->data.key)
InsertBST(T->lchild, e ); //将*S插入左子树
else if (e.key> T->data.key)
InsertBST(T->rchild, e); //将*S插入右子树
}
//- - - - -二叉排序树的创建- - - - -
/*【算法步骤】
* ① 将二叉排序树T初始化为空树。
* ② 读入一个关键字为key的结点。
* ③ 如果读入的关键字key不是输入结束标志,则循环执行以下操作:
* ·将此结点插入二叉排序树T中;
* ·读入一个关键字为key的结点。*/
void CreatBST(BSTree &T)
{//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
T=NULL; //将二叉排序树T初始化为空树
ElemType e;
cout<<"请输入关键字为key的结点,以-1结束:"<<endl;
cin>>e.key;
while(e.key!=ENDFLAG) //ENDFLAG为自定义常量,作为输入结束标志
{
InsertBST(T,e); //将此结点插入二叉排序树T中
cin>>e.key;
}
cout<<"二叉排序树创建完成"<<endl;
}
//- - - - -二叉排序树的删除- - - - -
int main(){
BSTree T;
CreatBST(T);
PritBST(T);
}
/home/lijing/CLionProjects/DataStructureAlgorithms2/BinarySearchTree
请输入关键字为key的结点,以-1结束:
6 9 23 12 11 45 23 -1
二叉排序树创建完成
6 9 11 12 23 45
Process finished with exit code 0
散列表
//
// Created by lijing on 23-12-7.
//
//- - - - -开放地址法散列表的存储表示- - - - -
#define m 20 //散列表的表长
#define MOD 13
typedef int KeyType; //关键字类型
typedef int InfoType; //其他数据项类型
typedef struct{
KeyType key; //关键字项
InfoType otherinfo; //其他数据项
}HashTable[m];
#define NULLKEY 0 //单元为空的标记
int H(KeyType key){
return key % MOD; //散列函数
}
//- - - - -线性探测法散列函数- - - - -
int SearchHash(HashTable HT,KeyType key)
{//在散列表HT中查找关键字为key的元素,若查找成功,返回散列表的单元标号,否则返回-1
int i,H0,Hi;
H0=H(key); //根据散列函数H(key)计算散列地址
if(HT[H0].key==NULLKEY) return -1; //若单元H0为空,则所查元素不存在
else if(HT[H0].key==key) return H0; //若单元H0中元素的关键字为key,则查找成功
else
{
for(i=1;i<m;++i)
{
Hi=(H0+i)%MOD; //按照线性探测法计算下一个散列地址Hi
if(HT[Hi].key==NULLKEY) return -1; //若单元Hi为空,则所查元素不存在
else if(HT[Hi].key==key) return Hi; //若单元Hi中元素的关键字为key,则查找成功
} //for
return -1;
} //else
}
线性表:顺序查找 二分查找 分块查找
//Sequential Search
// Created by lijing on 23-11-27.
#include "../../Define.h"
typedef int KeyType;
typedef int InfoType;
typedef struct{
KeyType key; //关键字域
InfoType otherinfo; //其他域
}ElemType;
typedef struct{
ElemType *R; //存储空间基地址
int length; //当前长度
}SSTable;
//--------------------------顺序查找--------------------------------------
//假设元素从ST.R[1]开始顺序向后存放,ST.R[0]闲置不用,查找时从表的最后开始比较
//顺序查找的平均时间复杂度为O(n),当n很大时,效率很低
//优点:实现简单,适用线性表的顺序存储结构,又适用于线性表的链式存储结构,
int Search_Seq(SSTable ST,KeyType key)
{ //在顺序表ST中顺序查找其关键字等于key的数据元素。
// 若找到,则函数值为该元素在表中的位置,否则为0
// for(int i=ST.length;i>=1;--i)
// if(ST.R[i].key==key) return i;//从后往前找,使用哨兵免去检测是否满足i》=1
// return 0;
ST.R[0].key=key; //“哨兵”
// 这个改进能使顺序查找在ST.length≥1000时,进行一次查找所需的平均时间几乎减少一半
for (int i = ST.length ; ST.R[i].key !=key ; ++i) {
return i;
}
}
//--------------------------折半查找/二分查找--------------------------------------
/*
折半查找(必须采用顺序查找,且表中元素按关键字有序排列),每查找一次,查找区间缩小一半。
不适用于数据元素经常变动的线性表
【算法步骤】
① 置查找区间初值,low为1,high为表长。
② 当low小于等于high时,循环执行以下操作:
·mid取值为low和high的中间值;
·将给定值key与中间位置记录的关键字进行比较,若相等则查找成功,返回中间位置mid;
·若不相等则利用中间位置记录将表对分成前、后两个子表。
如果key比中间位置记录的关键字小,则high取为mid-1,否则low取为mid+1。
③ 循环结束,说明查找区间为空,则查找失败,返回0。*/
int Search_Bin(SSTable ST,KeyType key)
{//在有序表ST中折半查找其关键字等于key的数据元素。若找到,则函数值为该元素在表中的位置,否则为0
int low=1;
int high=ST.length; //置查找区间初值
int mid;
while(low<=high)
{/*循环执行的条件是low<=high,而不是low<high,
因为low=high时,查找区间还有最后一个结点,还要进一步比较。*/
mid=(low+high)/2;
if(key==ST.R[mid].key) return mid; //找到待查元素
else if(key<ST.R[mid].key) high=mid-1; //继续在前一子表进行查找
else low=mid+1; //继续在后一子表进行查找
} //while
return 0; //表中不存在待查元素
}
//递归实现
//--------------------------分块查找--------------------------------------