关于查询的部分数据结构实现-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)

 

 

 

你可能感兴趣的:(数据结构)