试写出折半查找的递归算法。
#include <stdio.h>
#include <stdlib.h>
#define Maxsize 100
typedef int KeyType;
typedef char InfoType;
typedef struct
{
KeyType Key;
InfoType OtherInfo;
}elem;
typedef struct
{
elem *R;
int length;
}SSTable;
void initSSTable(SSTable& ST);
int Search_Bin(SSTable ST, KeyType key, int low, int high);
int main()
{
SSTable ST = { NULL,0 };
int i = 0;
KeyType key = 0;
int r = 0;
char choice = ';'initSSTable
()ST;printf
("请输入递增有序表中元素的个数:");scanf_s
(" %d",& .ST)length;for
( =i 1 ;<= i . ST;length++ i)printf
{
("请输入第%d个元素的值:",) i;scanf_s
(" %d",& .ST[R]i.)Key;}
while
( 1)printf
{
("\n请输入要查找到数:");scanf_s
(" %d",& )key;=
r Search_Bin (,ST, key1 ,. ST)length;if
( ==r - 1)printf
{
("%d查找失败。\n",)key;}
else
printf
{
("%d的位置为:%d\n",, key) r;}
printf
("是否继续?(y/Y)");scanf_s
(" %c",& )choice;if
( !=choice 'y' && != choice 'Y' )break
{
;}
}
return
0 ;}
void
initSSTable (&SSTable) ST.
{
ST=R ( *elem)malloc(sizeof()elem*) Maxsize;.
ST=length 0 ;}
//折半查找 递归
int
Search_Bin (,SSTable ST, KeyType keyint , lowint ) highif
{
( >low ) highreturn
{
- 1;}
int
= mid ( +low ) high/ 2 ;if
( ==key . ST[R]mid.)Keyreturn
{
; mid}
else
if ( >key . ST[R]mid.)Keyreturn
{
Search_Bin (,ST, key+ mid 1 ,) high;}
else
return
{
Search_Bin (,ST, key, low- mid 1 );}
}
习题2
#
试写一个判别给定二叉树是否为二叉排序树的算法。
include<stdio.h> #
include<stdlib.h> typedef
int ; KeyTypetypedef
char ; InfoTypetypedef
struct ;
{
KeyType Key;
InfoType OtherInfo}
;ElemTypetypedef
struct BTNode ;
{
ElemType datastruct
BTNode *; lchildstruct
BTNode *; rchild}
,BTNode*; BTree#
definetrue 1 #
definefalse 0 =
bool flag ; true//全局变量,初值为true. 若非二叉排序树,则置flag为false. =
BTree pre NULL ;void
initTree (&BTree) T;void
CreateTree (&BTree) T;void
JudgeBSTree (,BTree T& bool) flag;int
main ()=
{
BTree T NULL ;initTree
()T;CreateTree
()T;JudgeBSTree
(,T) flag;if
( ==flag 1 )printf
{
("该二叉树为排序二叉树。\n");}
else
printf
{
("该二叉树为非排序二叉树。\n");}
return
0 ;}
void
initTree (&BTree) T=
{
T NULL ;}
//创建普通二叉树
void
CreateTree (&BTree) T=
{
ElemType e 0 { ,'}'; printf(
"请输入结点的关键字域值(结点不存在时,输入0):");scanf_s(
" %d",&. )e;Keyif(
. ==e0Key ) =NULL
{
T ; }else
if
( . !=e0Key ) =(
{
T ) mallocBTree(sizeof())BTNode;->=
T;data CreateTree e(
->)T;lchildCreateTree(
->)T;rchild}}
//中序遍历输入的二叉树,判断是否递增
void
JudgeBSTree
( ,&BTree T) boolif flag(
{
&& )T JudgeBSTree flag(
{
->,T)lchild; flag//就是将原来中序遍历输出根结点的命令,替换为将该根结点值与其前一个值相比较if
(
== NULLpre ) =;
{
pre //pre只有在中序遍历到第一个结点时为空,后面的结点都不为空。而第一个结点不必判断。 T} else
if
( -> .pre<data->Key . T)data//每一个中序遍历的结点值T->data.Key都需要比前面一个结点值pre->data.Key大Key= ;
{
pre } Telse
=
;
{
flag } falseJudgeBSTree
(
->,T)rchild; flag}}
//中序遍历输入的二叉树,判断是否递增
void
JudgeBSTree
( ,&BTree T) bool ifflag(
{
) printfT(
{
"\n\n【a】T->data.Key = %d",->. T)data;Keyif(
-> )Tprintflchild(
{
"\n【a】T->lchild->data.Key = %d",->-> T.lchild)data;Key}else
printf
(
{
"\n【a】T->lchild->data.Key = #");}if
(
-> )Tprintfrchild(
{
"\n【a】T->rchild->data.Key = %d",->-> T.rchild)data;Key}else
printf
(
{
"\n【a】T->rchild->data.Key = #");}}
else
printf
(
{
"\n\n【a】T->data.Key = #");}if
(
) printfT(
{
"\n【1】开始 T = %d\n",->. T)data;Key}else
printf
(
{
"\n【1】开始 T = #\n");}if
(
&& )T if flag(
{
-> )Tprintflchild(
{
"\n【2】开始%d->lchild = %d \n",->. T,data->Key-> T.lchild)data;Key}else
printf
(
{
"\n【2】开始%d->lchild = # \n ",->. T)data;Key}JudgeBSTree
(
->,T)lchild;flagif(
-> )Tprintflchild(
{
"\n【3】%d->lchild = %d 结束\n",->. T,data->Key-> T.lchild)data;Key}else
printf
(
{
"\n【3】%d->lchild = # 结束\n ",->. T)data;Key}if
(
) printfpre(
{
"\n\n【b】pre->data.Key = %d \n",->. pre)data;Key}else
printf
(
{
"\n\n【b】pre->data.Key = # \n");}//就是将原来中序遍历输出根结点的命令,替换为将该根结点值与其前一个值相比较
if
(
== NULLpre ) =;
{
pre //pre只有在中序遍历到第一个结点时为空,后面的结点都不为空。而第一个结点不必判断。 T} else
if
( ->.pre<data->Key . T)data//每一个中序遍历的结点值T->data.Key都需要比前面一个结点值pre->data.Key大Key= ;
{
pre } Telse
=
;
{
flag } falseif
(
-> )Tprintfrchild(
{
"\n【4】开始%d->rchild = %d \n",->. T,data->Key-> T.rchild)data;Key}else
printf
(
{
"\n【4】开始%d->rchild = # \n ",->. T)data;Key}JudgeBSTree
(
->,T)rchild; flagif(
-> )Tprintfrchild(
{
"\n【5】%d->rchild = %d 结束\n",->. T,data->Key-> T.rchild)data;Key}else
printf
(
{
"\n【5】%d->rchild = # 结束\n ",->. T)data;Key}}
if
(
) printfT(
{
"\n【6】T = %d 结束 \n",->. T)data;Key}else
printf
(
{
"\n【6】T = # 结束\n");}}
习题3
#
include
已知二叉排序树采用二叉链表存储结构,根结点的指针为 T, 链结点的结构为 (lchild,data, rchild) , 其中lchild、rchild分别指向该结点左、右孩子的指针,data域存放结点的数据信息。
请写出递归算法,从小到大输出二叉排序树中所有数据值 ≥ x 的结点的数据。要求先找到第一个满足条件的结点后,再依次输出其他满足条件的结点。
【在中序遍历时判断】
<stdio.h># include
<stdlib.h># define
ENDFLAG- 1 //自定义常量,作为输入结束标志typedef int
; typedef KeyTypechar
; //二叉排序树的二叉链表存储表示 InfoTypetypedef
struct
; ;
{
KeyType Key}
InfoType otherinfo;
typedefElemTypestruct
BSTNode ; struct
{
ElemType dataBSTNode
* ;struct lchildBSTNode
* ;} rchild,
*BSTNode; void BSTreeInitBiTree
( &)BSTree; TvoidInsertBST
( &,BSTree) T; ElemType evoidCreateBST
( &)BSTree; TvoidpreOrderTraverse
( );BSTree TvoidInOrderTraverse
( );BSTree TvoidposOrderTraverse
( );BSTree TvoidJudge_x
( ,intBSTree T) ; xintmain
( )=NULL
{
BSTree T ; InitBiTree(
);TCreateBST(
);Tprintf(
"\n二叉排序树链表的先序序列为: ");preOrderTraverse(
);Tprintf(
"\n二叉排序树链表的中序序列为: ");InOrderTraverse(
);Tprintf(
"\n二叉排序树链表的后序序列为: ");posOrderTraverse(
);Tprintf(
"\n≥50的关键字为:");Judge_x(
,50T) ;return0
; }//初始化二叉排序树
void
InitBiTree
( &)BSTree= TNULL
{
T ; }//算法 7.5 二叉排序树的插入
//前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素
void
InsertBST
( &,BSTree) Tif ElemType e(
{
! )=T(
{
BSTree S ) mallocBSTree(sizeof())BSTNode;->=
S;data -> e=
SNULLlchild ; ->=
SNULLrchild ; =;
T //把新结点*S链接到已找到的插入位置 S} else
if
( . <e->Key . T)dataInsertBSTKey(
{
->,T)lchild; e}else
if
( . >e->Key . T)dataInsertBSTKey(
{
->,T)rchild; e}else
printf
(
{
"当二叉排序树T中存在关键字等于%d的结点,无法插入。\n",.) e;Keyreturn;
}}
//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void
CreateBST
( &)BSTreeInitBiTree T(
{
);T=0
ElemType e , { '}';printf ("请输入新结点的关键字key值:"
);scanf_s(" %d"
,&.) ;ewhileKey(.
!= )e//ENDFLAG为自定义常量-1,作为输入结束标志Key InsertBST ENDFLAG( ,
{
);T= e0,
e '}' { ;printf( "请输入新结点的关键字key值:")
;scanf_s(" %d",
&.); }e}Key//先序递归遍历二叉排序树void
preOrderTraverse
(
)
if ()BSTree T//只有当T不为空时才访问它的成员
{
printf (T" %d" ,
{
->.); TpreOrderTraversedata(Key->)
;preOrderTraverseT(lchild->)
;}T}rchild//中序递归遍历二叉排序树void
InOrderTraverse
(
)
if ()BSTree TInOrderTraverse
{
( ->T)
{
;printfT(lchild" %d",
->.); TInOrderTraversedata(Key->)
;}T}rchild//后序递归遍历二叉排序树void
posOrderTraverse
(
)
if ()BSTree TposOrderTraverse
{
( ->T)
{
;posOrderTraverseT(lchild->)
;printfT(rchild" %d",
->.); T}data}Key//输出大于等于x的关键字void
Judge_x
(
,
int )ifBSTree T( ) xJudge_x
{
( ->T,
{
);Tiflchild( x->.
>= )Tprintfdata(Key "%d " x,
{
->.); T}dataJudge_xKey(->
,
);T}rchild} x习题4
#
include
<stdio.h>
已知二叉树T的结点形式为(llink,data, count, rlink), 在树中查找值为X的结点,若找到, 则记数(count)加1; 否则,作为一个新结点插入树中,插入后仍为二叉排序树,写出其非递归算法。
include<stdlib.h> #
defineENDFLAG -
1//自定义常量,作为输入结束标志 typedef int; typedef
char ; KeyType//二叉排序树的二叉链表存储表示
typedef struct InfoType;
;
} ;
{
KeyType Keytypedef
InfoType otherinfostruct
BSTNodeElemType;
int ; struct
{
ElemType dataBSTNode
* count;
struct BSTNode* lchild;
} ,* rchild;
voidBSTNodeInitBiTree ( BSTree&
) ;voidBSTreeInsertBST T(&
, );BSTreevoid TCreateBST KeyType e(&
) ;voidBSTreepreOrderTraverse T()
; voidInOrderTraverseBSTree T()
; voidposOrderTraverseBSTree T()
; voidSearchBSTreeBSTree T(&
, );BSTreeint Tmain KeyType e()
= NULL;=
{
BSTree T 0 ;char
KeyType KEY = ';'InitBiTree
( choice ) ;CreateBST
()T;printf
("\n二叉排序树链表的先序序列为: "T);
preOrderTraverse();printf
("\n二叉排序树链表的中序序列为: "T);
InOrderTraverse();printf
("\n二叉排序树链表的后序序列为: "T);
posOrderTraverse();while
(1T)printf
( "\n\n请输入要查找的关键字值:");
{
scanf_s(" %d",&
);SearchBSTree( ,KEY);
printf(T"\n二叉排序树链表的先序序列为: " KEY);
preOrderTraverse();printf
("\n二叉排序树链表的中序序列为: "T);
InOrderTraverse();printf
("\n二叉排序树链表的后序序列为: "T);
posOrderTraverse();printf
("\n是否继续?(y/n)"T);
scanf_s(" %c",&
);if( !=choice'y'&&
!= 'Y'choice ) break ; choice } }return
{
0;
}
//初始化二叉排序树
void InitBiTree(
&
)
= NULL;BSTree} T//二叉排序树的插入(非递归)
{
T //二叉排序树T中不存在关键字等于key的数据元素时,插入该值.否则count++ voidInsertBST
(
&
,
) =NULLBSTree; T= KeyType e;
{
BSTree f = ()
BSTree q malloc T(
BSTree S sizeof (BSTree));->.BSTNode=;->
S=data0Key ; e//每查找成功了次数才加1,新建时次数为0
S->count = NULL; ->
S=lchild NULL ;if
S(rchild ! )//T为空树
= ;returnT; }
{
T //因为T可能为空树,所以不能把这种情况放在最前面 Sif
(->
.
==
) ->T++data;Key free e(
{
T)count;=
NULL;Sreturn;
S } while(
&&->
.
!= )q = q;dataifKey ( e->
{
f . q>
) =q->data;Key } eelse
{
q //if(q->data.Key < e) q=lchild->
;
} }
{
q if q(rchild)
->
++
; freeq(
{
q)count;=
NULL;S}else
S = ;//只知f是q的父节点,但是不清楚q是f的哪个子树
if
(
{
q -> S.
>
) ->f=data;Key } eelse
{
f->lchild = S;
}
}
{
f}rchild //算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的) S//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中
void
CreateBST
(
&
)
InitBiTree ()BSTree; T=
{
0;Tprintf(
KeyType Key "请输入新结点的关键字key值:" );
scanf_s(" %d",&
);while( !=Key)//ENDFLAG为自定义常量-1,作为输入结束标志
InsertBST (Key , ENDFLAG) ;
{
printf(T"请输入新结点的关键字key值:" Key);
scanf_s(" %d",&
);}} //先序递归遍历二叉排序树KeyvoidpreOrderTraverse
(
)
if
( )//只有当T不为空时才访问它的成员BSTree Tprintf
{
( "\n Key = %d, count = %d "T, ->
{
.,->) T;datapreOrderTraverseKey( T->count);
preOrderTraverse(T->lchild);
}}T//中序递归遍历二叉排序树rchildvoidInOrderTraverse
(
)
if
( )InOrderTraverseBSTree T(
{
-> )T;
{
printf(T"\n Key = %d, count = %d "lchild,->
.,->) T;dataInOrderTraverseKey( T->count);
}}T//后序递归遍历二叉排序树rchildvoidposOrderTraverse
(
)
if
( )posOrderTraverseBSTree T(
{
-> )T;
{
posOrderTraverse(T->lchild);
printf(T"\n Key = %d, count = %d "rchild,->
.,->) T;data}Key} T//创建后的查找与插入(非递归)countvoidSearchBSTree
(
&
,
) if(BSTree! T) KeyType eprintf
{
( "二叉排序树为空,查找失败。\n")T;
{
return;}=;
=NULL
;
BSTree p if T(
BSTree f -> .==
) printfT(data"%d查找成功。\n"Key , e)
{
;->++; ereturn;
T}countwhile(
&&->
.
!= )p = p;dataifKey ( e->
{
f . p>
) =p->data;Key } eelse
{
p = p->lchild;
}
}
{
p if p(rchild)
//说明找到了p->data.Key = e
->
++ ;pprintf (
{
p"%d查找成功。\n"count,)
;}else= e()
malloc
(
{
BSTree S sizeof (BSTree));->.BSTNode=;->
S=data0Key ; e->
S=count NULL ;->
S=lchild NULL ;=
S;rchild if (>
p -> S.
) ->e = f;data}Keyelse
{
f->rchild = S;
}
printf
{
f(lchild "%d查找失败,已插入。\n" S,
)
;}}习题5
e#include
<stdio.h>
#
假设一棵平衡二叉树的每个结点都标明了平衡因子b, 试设计一个算法,求平衡二叉树的高度。
<stdlib.h># define
ENDFLAG- 1
//自定义常量,作为输入结束标志typedef int ;typedef char
; //二叉排序树的二叉链表存储表示 KeyTypetypedef
struct ; InfoType;
}
; typedef
{
KeyType Keystruct
InfoType otherinfoBSTNode
;ElemTypeint
; //平衡因子(Balance Factor), struct
{
ElemType dataBSTNode
* bf; struct
BSTNode *; lchild}
, *; rchildvoid
InitBiTreeBSTNode( & BSTree)
; voidInsertBSTBSTree( T&,
) ;voidBSTreeCreateBST T( KeyType e&)
; voidBF_BSTreeBSTree( T&)
; voidpreOrderTraverseBSTree( T);
void InOrderTraverse(BSTree T);
void posOrderTraverse(BSTree T);
int Height(BSTree T);
int Balance_Factor(BSTree T);
int Height_BF(BSTree T);
int main(BSTree T)=
NULL ;InitBiTree(
{
BSTree T ) ;CreateBST
()T;BF_BSTree
()T;printf
("\n二叉排序树链表的先序序列为: "T);
preOrderTraverse();printf
("\n二叉排序树链表的中序序列为: "T);
InOrderTraverse();printf
("\n二叉排序树链表的后序序列为: "T);
posOrderTraverse();//假设已经平衡
printf(T"\n\n该平衡二叉树的高度为:%d",
Height_BF
()); return0T;}//初始化二叉排序树
void InitBiTree(
&
)
= NULL;BSTree} T//算法 7.5 二叉排序树的插入
{
T //前提:当二叉排序树T中不存在关键字等于e.key的数据元素时, 则插入该元素 voidInsertBST
(
&
,
) if(BSTree! T) KeyType e=
{
( )mallocT(
{
BSTree S sizeof (BSTree));->.BSTNode=;->
S=data0Key ; e->
S=bf NULL ;->
S=lchild NULL ;=
S;rchild //把新结点*S链接到已找到的插入位置 }else
T if S( <
->
. ) InsertBSTe ( T->data,Key)
{
;}Telselchildif e(>
->
. ) InsertBSTe ( T->data,Key)
{
;}Telserchildprintf e("当二叉排序树T中存在关键字等于%d的结点,无法插入。\n"
,
)
{
;return;} e}//算法7.6 二叉排序树的创建(在插入操作的基础上,且是从空的二叉排序树开始的)
//依次读人一个关键字为key的结点, 将此结点插人二叉排序树T中void
CreateBST
(
&
)
InitBiTree ()BSTree; T=
{
0;Tprintf(
KeyType Key "请输入新结点的关键字key值:" );
scanf_s(" %d",&
);while( !=Key)//ENDFLAG为自定义常量-1,作为输入结束标志
InsertBST (Key , ENDFLAG) ;
{
printf(T"请输入新结点的关键字key值:" Key);
scanf_s(" %d",&
);}} //全部创建完成后,根据中序遍历,求每个结点的平衡因子KeyvoidBF_BSTree
(
&
)
if ()BSTree BF_BSTreeT(
{
-> )T;
{
->=TBalance_Factorlchild()
T;bf BF_BSTree (->T);
}}T//先序递归遍历二叉排序树rchildvoidpreOrderTraverse
(
)
if
( )//只有当T不为空时才访问它的成员BSTree Tprintf
{
( "\nKey = %d, bf = %d "T, ->
{
.,->) T;datapreOrderTraverseKey(T->bf);
preOrderTraverse(T->lchild);
}}T//中序递归遍历二叉排序树rchildvoidInOrderTraverse
(
)
if
( )InOrderTraverseBSTree T(
{
-> )T;
{
printf(T"\nKey = %d, bf = %d "lchild,->
.,->) T;dataInOrderTraverseKey( T->bf);
}}T//后序递归遍历二叉排序树rchildvoidposOrderTraverse
(
)
if
( )posOrderTraverseBSTree T(
{
-> )T;
{
posOrderTraverse(T->lchild);
printf(T"\nKey = %d, bf = %d "rchild,->
.,->) T;data}Key} T//求高度bfintHeight
(
)
if
( !)BSTree Treturn
{
0 ;}Telse
{
int =Height
(
->
{
) m ; int=THeightlchild(->
) n ; if(T>rchild)return
+ 1m ; n}
{
else m return +1
;
}
{
} n } //根据高度求平衡因子int
Balance_Factor
(
)
int
= Height(BSTree T->
{
) left ; int=THeightlchild(->
) right ; return-T;rchild}//根据平衡二叉排序树的平衡因子求高度
//平衡二叉树,每个结点的平衡因子绝对值不超过1 left int rightHeight_BF
(
)
int
= 0;BSTree T=
{
; level while ()
BSTree p ++ T;
if (p->
{
level<0
) //p->bf == -1p=bf -> ;} else
{
p //if(p->bf == 1 || p->bf == 0) p=rchild->
;
} }
{
p return p;lchild}
习题6
//除留余数法构造散列函数,“链地址法”处理冲突
# levelinclude
<stdio.h>
分别写出在散列表中插入和删除关键字为K的一个记录的算法,设散列函数为H, 解决冲突的方法为链地址法。
include
<stdlib.h># include
<math.h># define
m13 #
defineNULLKEY 0 typedef
int; typedef char
; typedef KeyTypestruct
KeyNode ; InfoType;
struct KeyNode *
{
KeyType Key;
InfoType OtherInfo}
; voidCreateHash next(
[KeyNode]
) ;voidKeyNode HTInsert([]
, );KeyNode HTintSearchHash( KeyType key[]
, );KeyNode HTintH( KeyType key);
int maxPrimeNumber(KeyType keyint)
; intcheckPrimeNumber( nint)
; voidDelete( n[]
, );KeyNode HTvoidprintHashTable( KeyType key[]
) ;intKeyNode HTmain()[
] =0}
{
KeyNode HT;m= 0 { ; =0
KeyType k1 ; char=
KeyType k2 ';' CreateHash(
) choice ; printHashTable(
);HTwhile(
1)HTprintf(
"\n\n请输入要插入的数值:" );scanf_s
{
(" %d",&)
;Insert(, )k1;printHashTable
()HT; k1printf(
"\n\n请输入要删除的数值:")HT;scanf_s
(" %d",&)
;Delete(, )k2;printHashTable
()HT; k2printf(
"\n\n是否继续?(y/Y)")HT;scanf_s
(" %c",&)
;if(!= 'y'choice&&!=
'Y' )choice break ; } choice } return0
{
;}
//创建散列表
void
CreateHash ([
]
)
int =0KeyNode HT;int=
{
0 i ; int=
0 KEY ; for(
= flag 0 ;<
; ++i ) [] i . m= i;[
{
HT]i.=Key NULL NULLKEY;
HT}ifor(next = 1;
<=
; ++i ) printf( i "请输入第%d个关键字(结束时输入-1):" m, i);
{
scanf_s(" %d", i&)
;//记录个数可以小于表长度if( !=KEY-1 )
= SearchHashKEY ( ,);
{
flag if (==HT- KEY1)
Insert (flag , );}
{
elseprintfHT( KEY"该元素已存在,无法插入,请重新输入。\n")
;
--
{
;}}elsebreak
i;}
}
if
(
{
>)
printf
(
"散列表已满。" )i ; mreturn
{
;}}//散列表的查找int
SearchHash(
[
]
,
) int=KeyNode HTH() KeyType key;
{
* H0 = []key.;
KeyNodewhile p ( HT!=H0NULL)nextif
( ->p == )return
{
; //找见了p}Key = key->
{
; H0} return
-
p 1 p;next//没找见
}
//散列表的插入(链地址法处理冲突) voidInsert( [
]
,
) int=KeyNode HTH() KeyType key;
{
* H0 = []key.;
KeyNodewhile p ( HT!=H0NULL)nextif
( ->p == )printf
{
( "该元素已存在,无法插入。\n"p)Key ; key}
{
=->;}*
=
p ( p*next)
malloc
KeyNode( r sizeof (KeyNode));->=;KeyNode->=[
r]Key . key;
r[next ] HT.H0=;next}
HT//散列函数H0/* 采用除留余数法构造散列函数,选择p为小于表长m的最大质数 */intnext H r(
)
int
=
maxPrimeNumber ()KeyType key;
{
return p % ;}m//确定[0,n]范围内的最大质数int
maxPrimeNumber key ( pint
)
int
= 0;int n=
{
checkPrimeNumber i ( 0)
; status int =0;for(
= max 0 ;<=
; ++i ) =checkPrimeNumber i ( n) i;if
{
status ( )=i;}
} returnstatus;
{
max } i//判断一个数是否是质数
int
checkPrimeNumber
( maxint
)
int
= 0;int n=
{
floor i ( sqrt(
) sq ) ;if(<=n1)return
0 ;n } if(
{
== 2||
==
3 )n return 1 ; n } //只有6x-1和6x+1的数才有可能是质数(但不一定就是,如n=35,还需要继续判断)if
{
( %6
!=
1
&& %n 6 != 5 ) //n=4和n=6时,n%6满足该if条件,返回false,正好符合情况 n return ; } /* 如果 i 是简单类型(int ,char),在使用层面,i+=6 与 i=i+6 做的事是一样的,
都是将 i 的值加了6,但生成的可执行代码不一样,且i+=6 与 i=i+6 运行的效率不同,i+=6 肯定更快。 *///只判断 该与6的倍数相邻的数n 能否被 其它不超过sq 且 也与6的倍数相邻的数i和i+2 整除 // 同样因为“只有与6的倍数相邻的数才可能是质数”,所以用i和i+2来判断(i=5... i+2=7...)。
{
// 定理:如果一个数n不能整除 比它小的任何素数(比n小的全部素数一定都包含在i和i+2中),那么这个数n就是素数。 falsefor
(
=
5
;
<=
; +=i 6 )if i ( sq% i== 0||
{
% (n + i 2 ) == n 0 )i return 0; } }//此处for循环中,仍然找的是整数n的因数,所以仍然可以使用定理:如果一个数m不是质数,那么它必定有一个因子≤√m,另一个≥√m。所以i仍然判断到sq就可以。
{
//真命题“如果数n存在一个大于√n的整数因数,那么它必定存在一个小于√n的整数因数。”的逆否命题也是真命题。 // 即如果一个数n没有小于√n的整数因数,那么它也一定不会有大于√n的整数因数(除了它自己)。//n = 5 和 n=7 时,不会进入if判断语句,也不会进入for循环,而是直接返回true,此时也判断正确
return
;
}
void
printHashTable
(
[ true]
)
int =0KeyNode HT;*=
{
NULL i ; printf(
KeyNode"\n散列表中的元素为:" p ) ;for
(=0;<
; ++i ) if( i [ m] i.!=
{
NULL )HTprintfi("\n在%d个位置处,保存的关键字有:"next , +1
{
);for( i=[].
; ;p = HT->i)printfnext( p"%d " p , p->next)
{
;}}//空槽(链表不为空的)不输出,但是其它的元素还是要输出 p//链地址法中,散列表每个位置的HT[i].key成员并不存储任何数据,通常设置为 NULLKEY或者不使用Key}}
//散列表的删除
void
Delete
(
[
]
,
) int=KeyNode HTH()KeyType key;
{
* H0 = []key.;
KeyNode* p = HTNULLH0;whilenext(
KeyNode!= q NULL )if
( ->p == )break
{
; }p=Key ; key=
{
->;
}
q if p(
p ! p)next[
]
. =->q;
{
HT}H0else->next = p->next;
}
if
{
q(next ! p)nextprintf
(
"%d查找失败,无法删除。\n" ,)p;
{
}free() key;=
NULL
;}p
p