关于查询的部分数据结构实现C语言

一, Sequence Search 

View Code
// Sequence_Search
// yefeng1627
#include<stdio.h> 
#include<stdlib.h>
#define True 1
#define False 0
#define MaxLength 100

typedef int KeyType;
typedef int DataType;

typedef struct{
    KeyType key;     //关键字域
    DataType other; //其它属性域        
}ElemType;
typedef struct{
    ElemType *elem;    //存放数据
    int    length;        //表的长度    
}SeqTable;


int SeqSearch( SeqTable st, KeyType key, int *Location ){
    // 顺序查找,查找成功返回 true, 查找失败返回 false
    int i;
    *Location = -1;     
    for( i = 0; i < st.length; i++){
        if( st.elem[i].key == key ){
            *Location = i;
            return True;    
        }//end if
    }//end for
    return False;
}
int main(){
    // 初始化顺序表内信息
    int i, Location, flag;
    SeqTable st;
    KeyType key;
    st.length = 10;
    st.elem = (ElemType *)malloc( MaxLength*sizeof(ElemType));
    for( i = 0; i < 10; i++ ){ 
        st.elem[i].key = i;
        st.elem[i].other = i*10;
    }     
    // 查询    key = 3 
    key = 3; 
    if( SeqSearch( st, key, &Location ) == True )
        printf("顺序表查找成功,该数据元素的位置为%d",Location);   
    else
        printf("顺序表查找失败!");

     return 0;
}

二. Binary Search

View Code
// Binary_Search
// yefeng1627
#include<stdio.h> 
#include<stdlib.h>
#define True 1
#define False 0
#define MaxLength 100

typedef int KeyType;
typedef int DataType;

typedef struct{
    KeyType key;     //关键字域
    DataType other; //其它属性域        
}ElemType;
typedef struct{
    ElemType *elem;    //存放数据
    int    length;        //表的长度    
}SeqTable;


int BinSearch( SeqTable st, KeyType key, int *Location ){
    // 顺序查找,查找成功返回 true, 查找失败返回 false
    int i;
    int Low = 0, High = st.length-1, Mid;
    *Location = -1;     
    while( Low <= High ){
        Mid = (Low+High)/2;
        if( st.elem[Mid].key == key ){
            *Location = Mid;    
            return True;
        } 
        else if( st.elem[Mid].key < key ) Low = Mid+1;     
        else High = Mid-1;
    }
    return False;
}
int main(){
    // 初始化表内信息,以key递增进行初始化 
    int i, Location, flag;
    SeqTable st;
    KeyType key;
    st.length = 10;
    st.elem = (ElemType *)malloc( MaxLength*sizeof(ElemType));
    for( i = 0; i < 10; i++ ){ 
        st.elem[i].key = i;
        st.elem[i].other = i*10;
    }     
    // 查询    key = 3 
    key = 3; 
    if( BinSearch( st, key, &Location ) == True )
        printf("二分查找成功,该数据元素的位置为%d",Location);   
    else
        printf("顺序表查找失败!");

     return 0;
}

三. Block Search

View Code
// Block Search
// yefeng1627
#include<stdio.h>
#include<stdlib.h>
#define True 1
#define False 0

#define MaxLen 100 //索引表的最大长度

typedef int DataType;
typedef int KeyType; 
// 顺序表定义
typedef struct{
    KeyType key;     //关键字域
    DataType other; //其它属性域        
}ElemType;
typedef struct{
    ElemType elem[MaxLen];    //存放数据
    int    length;                //表的长度    
}SeqTable;

// 索引表定义 
typedef struct{
    KeyType key;
    int Address;    
}IndexType; //索引表的元素数据类型 

typedef struct{
    IndexType elem[MaxLen];    //存放数据
    int length;                //表的长度    
}IndexTable;    // 索引表类型 


int Block_Search( SeqTable st, IndexTable idx, KeyType key, int *Location ){
    //分块查找,查找成功返回 True, 查找失败返回False
    int i;
    int IdxAddress = -1;
    int b = st.length/idx.length + 1; //子表中元素个数
    *Location = -1;    
    //索引表采用顺序查找
    for( i = 0; i < idx.length; i++ ){
        if( idx.elem[i].key > key ){
            IdxAddress = i-1;
            break;
        }// end if
    } 
    if( i >= idx.length ) False;
    //查找表某亦子表顺序查找
    for( i = idx.elem[ IdxAddress ].Address; i < idx.elem[ IdxAddress ].Address+b && i < st.length; i++ )
        if( st.elem[i].key == key ){
            *Location = i;
            return True;    
        }//end if
    return False;
}
 

int main(){
    KeyType key;    //关键域 
    SeqTable st;    //顺序表 
    IndexTable idx; //索引表 
    int i, Location;
    
    // 初始化顺序表 , 顺序表key值 从小到大 
    st.length = 12;
    for( i = 0; i < 12; i++){
        st.elem[i].key = i*2;
        st.elem[i].other = i*12;
    } 
    // 初始化子表以及索引表  
    idx.length = 4;    
    for( i = 0; i < 4; i++){ // 将顺序表st划分为四块 
        idx.elem[i].key = st.elem[ i*3 ].key; //索引表中存储当前块最小值 
        idx.elem[i].Address = i*3;        // 记录索引地址 
    }
    // 查询 
    key = 10; 
    if( Block_Search( st, idx, key, &Location ) == True )
        printf("分块查找成功,该数据元素的位置为%d",Location);   
    else
        printf("查找失败!");
    
    return 0;
}

四. Hash Search

View Code
//    Hash Search
//    yefeng1627
#include<stdio.h> 
#include<stdlib.h>
#define True 1
#define False 0
#define MaxLength 100
#define N 1010


typedef int KeyType;
typedef int DataType;

//顺序表定义 
typedef struct{
    KeyType key;     //关键字域
    DataType other; //其它属性域        
}ElemType;
typedef struct{
    ElemType elem[N];    //存放数据
    int    length;        //表的长度    
}SeqTable;

//哈希表定义 
typedef struct node{
    KeyType key;    
    int Address;
    struct node *next; 
}HashTable;
 

KeyType Get_New_Key( KeyType key ){
    KeyType new_key = (key + 97) % 107; // 哈希函数,用于离散化数据    
    return new_key; 
}     
//使用链地址插入 
void insert( HashTable *ht, KeyType key, int location ){
    KeyType new_key = Get_New_Key( key );  
    HashTable *p = (HashTable *)malloc( sizeof(HashTable) );
    p->key = key;
    p->Address = location;
    p->next = NULL;
        
    p->next = ht[ new_key ].next;
    ht[new_key].next = p;
    
}

//使用链地址法查询 
int Hash_Search( HashTable *ht, KeyType key, int *location ){
    HashTable *p = ht[ Get_New_Key(key) ].next;     
    *location = -1;
    while( p != NULL ){ 
        if( p->key == key ){
            *location = p->Address;
            return True;    
        }    
        p = p->next;
    }
    return False;
}

void Free( HashTable *p ){
    if( p->next ) Free( p->next );
    free( p );    
}
void Free_Space( HashTable *ht ){ 
    for(int i = 0; i < 110; i++){
        if( ht[i].next ) Free( ht[i].next );     
    }
}
int main(){
    //初始化顺序表中元素, 顺序表元素key没有规律
    //为了表示方便,我们利用一个包含10个元素的无序数组初始化顺序表     
    HashTable ht[N]; // 定义哈希表 
    SeqTable st; 
    KeyType key;
    int a[10] = { 65,1,45,10,35, 20,75,50,40,31 };  
    int location;
    
    // 初始化哈希链表中指针都为空
    for(int i = 0; i < 107; i++)
        ht[i].next = NULL;
         
    st.length = 10;
    for(int i = 0; i < 10; i++){
        st.elem[i].key = a[i];
        st.elem[i].other = 0; //其它信息 
    }
    //使用线性表初始化哈希表, 使用链地址法 
    for(int i = 0; i < 10; i++)
        insert( ht, st.elem[i].key, i );    
    //查询
    key = 75;
    if( Hash_Search( ht, key, &location ) == True )
        printf("哈希链表查找成功,该数据元素的位置为%d",location);   
    else
        printf("查找失败!");
    
    Free_Space( ht ); //递归回收内存 
    return 0;    
}

五. Binary Sort Tree

View Code
// Binary Sort Tree
// yefeng1627
#include<stdio.h>
#include<stdlib.h>
#define False 0
#define True 1
//**********
//重点说明: 
//    对于指针操作,若需要通过
//  作为参数,改变指针指向,则需使用二维指针
//  来改变其指向。 因为指针存储的是其指向的地址。 
//**********
typedef int DataType;
typedef int KeyType;
typedef struct BinTNode{
    KeyType key;    //关键字域 
    DataType other; //其它属性域 
    BinTNode *lchild, *rchild;
}BinTNode, *BiTree;
  
void print( BiTree T ){
    // 中序遍历二叉排序树 T, 并输出关键域  
    if( T == NULL ) return; 
    if( T->lchild != NULL ) 
        print( T->lchild );
    printf("%d ", T->key );
    if( T->rchild != NULL )
        print( T->rchild );    
}

//对于指针 C, F 而言,其需要改变传入进来指针的指向 
int BSTSearch( BiTree T, BiTree *C, BiTree *F, KeyType x ){  
    //在二叉排序树T上查找关键码为x的元素,若找到返回True,且C指向该节点,F指向其父节点
    //否则,返回false,且C指向查找失败的最后一个节点
    *C = T;
    while( *C ){//从根节点开始查找 
        if( x > (*C)->key ){//x大于当前节点C的元素关键值 
            *F = *C;
            *C = (*C)->rchild;    //将当前节点C的右子树的根节点置为新根 
        }
        else if( x < (*C)->key ){//x小于当前节点C的元素关键值 
            *F = *C;
            *C = (*C)->lchild;    
        }
        else    return True;
    }//end while
    return False;
}

int InsertNode( BiTree *T, KeyType x ){
    //在二叉排序树T,上插入关键值为x的节点
//    system("pause");
    BinTNode *p = *T, *q = NULL, *s;
    if( BSTSearch( *T, &p, &q, x ) == False ){ //在*T为根的子树上查找  
        s = (BinTNode *)malloc( sizeof(BinTNode) ); //申请节点,并赋值
        s->key = x;
        s->lchild = NULL;
        s->rchild = NULL;  
        if( q == NULL ) *T = s;    //向空树中插入时 
        else{
            if( x > q->key )    q->rchild = s;    //插入节点为p的右孩子
            else    q->lchild = s;    //插入节点为p的左孩子 
        }//end if-else 
        return True;
    }//end-if
    return False;
}

int CreateBST( BiTree *T, KeyType *a, int num ){
    // 构造二叉排序树 T 
    *T = NULL;
    for(int i = 0; i < num; i++){
        InsertNode( T, a[i] );     
    }
    return True;
}

int DeleteNode( BiTree *T, KeyType x ){
    BinTNode *c, *f, *child;
    if( BSTSearch( *T, &c, &f, x ) == True ){ //若找到待删除节点 (*c所指) 
        if( c->lchild == NULL && c->rchild == NULL ){
            //情况1:待删节点为叶子节点
            if( f ){
                
                //待删节点有父节点,则非根节点
                if( f->lchild == c )    f->lchild = NULL;
                else    f->rchild = NULL;    
            }    
            else//待删节点为根节点
                *T = NULL;
            free( c ); //释放 c指针所指内存    
        }
        else if( c->lchild == NULL ){
            //情况2: 待删节点的左子树为空,用待删除的右子树替代该节点
            if( f ){ //待删节点双亲节点不为空 
                if( f->lchild == c ) // 待删节点为其父节点左儿子 
                    f->lchild = c->rchild; 
                else    f->rchild = c->rchild;    //待删节点为其父节点右儿子 
            }    
            else    *T = c->rchild;
            free( c );
        }
        else if( c->rchild == NULL ){
            //情况3: 待删节点的右子树为空,用待删除的左子树替代该节点
            if( f ){ //待删节点双亲节点不为空 
                if( f->lchild == c ) //待删节点为其父节点左儿子
                    f->lchild = c->lchild;
                else    f->rchild = c->lchild; 
            }    
            else    *T = c->lchild;
            free( c );
        }
        else{
            //情况4:待删节点的左右子树均不为空
            // 用右子树代替待删节点,同时将待删除
            // 节点的左子树收为,右子树,中序首点的左儿子
            child = c->rchild;
            while( child->lchild ) //找待删节点右子树中的 中序首点
                child = child->lchild; 
            // 将待删节点的左子树收为 child的左孩子 
            child->lchild = c->lchild; 
            if( f ){ //待删除节点的右子树不为空 
                if( f->lchild == c ) //
                    f->lchild = c->rchild;  
                else    
                    f->rchild = c->rchild;
            }
            else *T = c->rchild;
            free( c );
        }
        return True;
    }
    return False;    
}//End of DeleteNode


int main(){
    // 数据定义 
    KeyType a[7] = {49,55,25,39,63,13,2};
    BiTree T;
    BinTNode *c = NULL, *f = NULL;
    KeyType x; 
    // 创建二叉排序数 
    CreateBST( &T, a, 7 );
    
    //中序遍历输出二叉排序树节点信息
    printf("构造成功,中序遍历为:\n"); 
    print( T );
    printf("\n"); 
    // 查询
    x = 39;
    if( BSTSearch( T, &c, &f, x ) == True )
            printf("二叉排序树查找成功!\n");     
    else    printf("查找失败!\n");  
    // 删除 
    //*******************
    // 删除操作四种情况测试
    // Case 1: x = 39 , 左右子树皆为空
    // Case 2: x = 55 , 左子树为空
    // Case 3: x = 13 , 右子树为空
    // Case 4: x = 25 , 左右子树均不为空 
    //*******************
    x = 25; //删除关键域为2的节点 
    printf("删除操作前,二叉排序树,中序遍历为:\n");
    print( T );  puts(""); 
    DeleteNode( &T, x ); 
    printf("删除操作后,二叉排序树,中序遍历为:\n");
    print( T );  puts("");

    return 0; 
}

 六. Binary Balance Tree. (AVL)

 

原文地址:https://www.cnblogs.com/yefeng1627/p/3001674.html