《数据结构(C语言版)第二版》第七章-查找(算法设计题)

admin2024-09-05  29

习题1

试写出折半查找的递归算法。

#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

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第1张

#

试写一个判别给定二叉树是否为二叉排序树的算法。

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

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第2张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第3张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第4张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第5张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第6张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第7张

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>

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第8张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第9张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第10张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第11张

#

已知二叉树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> #

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第12张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第13张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第14张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第15张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第16张

include

假设一棵平衡二叉树的每个结点都标明了平衡因子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>

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第17张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第18张

#

分别写出在散列表中插入和删除关键字为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  


《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第19张
《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第20张

《数据结构(C语言版)第二版》第七章-查找(算法设计题),在这里插入图片描述,第21张

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!