//查找
#include<stdio.h>
#include<stdlib.h>
//定义一个待查找顺序表
#define MAXSIZE 20 // 顺序表最大长度
typedef int KeyType; //定义关键字类型
typedef struct{
KeyType key; //关键字项
char otherinfo; //其他数据项这里用char举例
}ElemType;
typedef struct{ //顺序表结构类型定义
ElemType *r; // r[0] 不用或用作哨兵
int length; //表长
}SS,*SSTable; //Sequential Search Table
//SSTable ST; //定义顺序表ST
//顺序查找
int Search_Seq0(SSTable ST,KeyType key){
ST->r[0].key=key; //哨兵
for(int i=1;i<=ST->length;i++){
if(ST->r[i].key==key){
return i;
}
}
return 0;
}
int Search_Seq(SSTable ST,KeyType key){
ST->r[0].key=key;
int i;
for(i=ST->length;ST->r[i].key!=key;i--);
return i;
}
//折半查找:有序表才能折半查找!
int Search_Bin(SSTable ST,KeyType key){
int low=1,high=ST->length;
while(low<=high){
int mid=(low+high)/2;
if(key==ST->r[mid].key) return mid;
else if(key>ST->r[mid].key){
low=mid+1;
}
else high=mid-1;//key<mid到前半段找
}
return 0;//查找失败
}
//递归Recursion折半查找
int SearchBinRecursion(SSTable ST,int key,int low,int high){
if(low>high) return 0; //找不到
int mid=(low+high)/2;
if(key==ST->r[mid].key) return mid;
else if(key>ST->r[mid].key)
return SearchBinRecursion(ST,key,(mid+1),high);
else SearchBinRecursion(ST,key,low,(mid-1));
}
//二叉排序链表建立
//typedef struct{
// KeyType key;
// char otherinfo;
//}ElemType;
typedef struct BSTNode{
ElemType data;
struct BSTNode *lch,*rch;
}BSTNode,*BSTree;
//二叉链表录入
BSTree CreateBSTree(){
BSTree T;
ElemType tree;
scanf("%d-",&tree.key);
if(tree.key!=0){ //0代表空位
T=(BSTree)malloc(sizeof(BSTNode));
T->data=tree;
T->lch=CreateBSTree();
T->rch=CreateBSTree();
}
else T=NULL;
return T;
}
//二叉排序树的插入
BSTree InsertBST(BSTree T,int key){
ElemType e;
e.key=key;
e.otherinfo='f';
if(!T){//如果T为NULL
BSTree S=(BSTree)malloc(sizeof(BSTNode));
S->data=e;
S->lch=S->rch=NULL;//把新结点*S作为叶子结点
T=S; //把新结点*S链接到插入位置T
}
else if(e.key<T->data.key) //如果key<当前值插入左子树
T->lch=InsertBST(T->lch,key);
else if(e.key>T->data.key) //key>当前值则插入右子树
T->rch=InsertBST(T->rch,key);
return T;
}
//二叉树建立
int a[9]={5,3,2,1,4,7,6,8,-1};
int i=0;
BSTree CreatBST(){
BSTree T=NULL;
int key;
key=a[i++]; //scanf("%d,",&key);
while(key!=-1){ //-1作为结束符
T=InsertBST(T,key);
key=a[i++];//scanf("%d,",&key);
}
return T;
}
//二叉排序链表的查找 返回key结点
BSTree SearchBSTree(BSTree S,int key){
if((!S)||key==S->data.key) return S;
else if(key>S->data.key) S=SearchBSTree(S->rch,key);
else S=SearchBSTree(S->lch,key);
return S;
}
//删除结点函数
BSTree deleteNode(BSTree T){
BSTree p;
if(T->lch==NULL&&T->rch==NULL){ //叶子结点
p=T;
T=NULL;
free(p);
return T;
}
else if(T->rch==NULL){ //右子树为空
p=T;
T=T->lch;
free(p);
return T;
}
else if(T->lch==NULL){ //左子树为空
p=T;
T=T->rch;
free(p);
return T;
}
else{ //左右子树都不为空
//拿左子树上最大值替换T
BSTree parent=T;
BSTree pre=T->lch;
//左子树最右支就是左子树最大数
while(pre->rch){
parent=pre; //parent保存pre上一个结点
pre=pre->rch;
}
T->data=pre->data; //pre是左支最大值替换T
if(parent!=T){ //如果T有右子树则上while执行parent不等于T
parent->rch=pre->lch; //则把pre左子树接到上级右子树
}
else{ //T 无右支while(pre->rch)未执行
T->lch=pre->lch; //则把左支接上去
}
free(pre);
return T;
}
}
//二叉排序树的删除
BSTree DeleteBST(BSTree T,int key){
//找到这个结点位置
if(!T) return T;
else{
if(T->data.key==key)
T=deleteNode(T);
else if(key>T->data.key)
T->rch=DeleteBST(T->rch,key);
else T->lch=DeleteBST(T->lch,key);
return T;
}
}
//二叉树中序遍历
int InOrder(BSTree T){
if(!T) return 0;
else{
InOrder(T->lch);
printf("%d ",T->data.key);
InOrder(T->rch);
}
}
//把二叉树变为双向链表
BSTree pre=NULL;
BSTree Change(BSTree T){//LBR中序线索化
BSTree p=T;
if(!p) return NULL;
else{
p->lch= Change(p->lch);
if(!p->lch){
p->lch=pre;
}
if(pre&&!pre->rch){
pre->rch=p;
}
pre=p;
p->rch=Change(T->rch);
}
return p;
}
BSTree ChangeB(BSTree T){
T=Change(T);
/*根应该指向左子树的右子树或右子树的左子树*/
BSTree p=T; pre=NULL;
while(p->lch){
pre=p; p=p->lch;
if(p->rch!=pre && pre->lch!=p->rch){
pre->lch=p->rch;
}
}
pre=NULL;p=T;
while(p->rch){
pre=p;p=p->rch;
if(p->lch!=pre && pre->rch!=p->lch){
pre->rch=p->lch;
}
}
while(p->lch){
p=p->lch;
}//找到链表头节点返回
return p;
}
int main(){
//SS SS;
// SSTable ST=(SSTable)malloc(sizeof(SS));
// ST->r=(ElemType*)malloc(21*sizeof(ElemType));
// ST->length=20;
// for(int i=1;i<=20;i++){
// ST->r[i].key=i;
// ST->r[i].otherinfo='z';
// }
// int a=Search_Seq(ST,3);
// int b=Search_Seq0(ST,17);
// int c=Search_Bin(ST,1);
// int d=SearchBinRecursion(ST,7,1,20);
// printf("%d %d %d %d\n",a,b,c,d);
//BSTree T=CreateBSTree();
BSTree T=CreatBST();
BSTree S=SearchBSTree(T,6);
printf("%d %p %p\n",S->data.key,S->lch,S->rch);
InOrder(T);printf("\n");
// T=DeleteBST(T,4);
// InOrder(T);printf("\n");
T=ChangeB(T);
while(T){
printf("%d ",T->data.key);
T=T->rch;
}
return 0;
}
查找和二叉排序树变双向链表备忘
于 2022-04-12 13:05:41 首次发布