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