061.二分搜索和冒泡排序

本篇博客简要的实现了二分搜索和冒泡排序的汇编写法。下面简要的介绍这两种简单的算法。

        在计算机科学中,二分查找算法(英语:binary search algorithm),也称折半搜索算法(英语:half-interval search algorithm)、对数搜索算法(英语:logarithmic search algorithm),是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。
        二分查找算法在情况下的复杂度是对数时间,进行O(log n)次比较操作(n在此处是数组的元素数量,O是大O记号,log 是对数)。二分查找算法使用常数空间,无论对任何大小的输入数据,算法使用的空间都是一样的。除非输入数据数量很少,否则二分查找算法比线性搜索更快,但数组必须事先被排序。尽管特定的、为了快速搜索而设计的数据结构更有效(比如哈希表),二分查找算法应用面更广。
        二分查找算法有许多中变种。比如分散层叠可以提升在多个数组中对同一个数值的搜索。分散层叠有效的解决了计算几何学和其他领域的许多搜索问题。指数搜索将二分查找算法拓宽到无边界的列表。二叉搜索树和B树数据结构就是基于二分查找算法的。
在这里插入图片描述
        冒泡排序(英语:Bubble Sort)又称为泡式排序,是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。冒泡排序对n个项目需要O(n2)的比较次数,且可以原地排序。尽管这个算法是最简单了解和实现的排序算法之一,但它对于包含大量的元素的数列排序是很没有效率的。冒泡排序是与插入排序拥有相等的运行时间,但是两种算法在需要的交换次数却很大地不同。在最坏的情况,冒泡排序需要O(n2)次交换,而插入排序只要最多O(n)交换。冒泡排序的实现(类似下面)通常会对已经排序好的数列拙劣地运行O(n2),而插入排序在这个例子只需要O(n)个运算。因此很多现代的算法教科书避免使用冒泡排序,而用插入排序取代之。冒泡排序如果能在内部循环第一次运行时,使用一个旗标来表示有无需要交换的可能,也可以把最优情况下的复杂度降低到O(n)。在这个情况,已经排序好的数列就无交换的需要。若在每次走访数列时,把走访顺序反过来,也可以稍微地改进效率。有时候称为鸡尾酒排序,因为算法会从数列的一端到另一端之间穿梭往返。
        冒泡排序算法的运作如下:
        比较相邻的元素。如果第一个比第二个大,就交换他们两个。
        对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,
        最后的元素会是最大的数。针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。由于它的简洁,冒泡排序通常被用来对于程序设计入门的学生介绍算法的概念。

        下面给出冒泡排序以及二分搜索算法的汇编语言实现过程。

BinarySearch.inc

; BinarySearch.inc - prototypes for procedures used in
; the BubbleSort / BinarySearch program.


; Search for an integer in an array of 32-bit signed
; integers.


BinarySearch PROTO,
	pArray:PTR DWORD,		; pointer to array
	Count:DWORD,			; array size
	searchVal:DWORD			; search value


; Fill an array with 32-bit signed random integers
FillArray PROTO,
	pArray:PTR DWORD,		; pointer to array
	Count:DWORD,			; number of elements
	LowerRange:SDWORD,		; lower range
	UpperRange:SDWORD		; upper range


; Write a 32-bit signed integer array to standard output
PrintArray PROTO,
	pArray:PTR DWORD,
	Count:DWORD


; Sort the array in ascending order
BubbleSort PROTO,
	pArray:PTR DWORD,
	Count:DWORD

FillArray.asm

TITLE FillArray Procedure                 (FillArray.asm)

INCLUDE Irvine32.inc

.code
;------------------------------------------------------------
FillArray PROC USES eax edi ecx edx,
	pArray:PTR DWORD,			; pointer to array
	Count:DWORD,				; number of elements
	LowerRange:SDWORD,			; lower range
	UpperRange:SDWORD			; upper range
;
; Fills an array with a random sequence of 32-bit signed
; integers between LowerRange and (UpperRange - 1).
; Returns: nothing
;-----------------------------------------------------------
	mov	edi,pArray				; EDI points to the array
	mov	ecx,Count	            ; loop counter
	mov	edx,UpperRange
	sub	edx,LowerRange	        ; EDX = absolute range (0..n)
	cld                         ; clear direction flag

L1:	mov	eax,edx	                ; get absolute range
	call	RandomRange
	add	eax,LowerRange	        ; bias the result
	stosd		                ; store EAX into [edi]
	loop	L1

	ret
FillArray ENDP

END

PrintArray.asm

TITLE PrintArray Procedure                  (PrintArray.asm)

INCLUDE Irvine32.inc

.code
;-----------------------------------------------------------
PrintArray PROC USES eax ecx edx esi,
	pArray:PTR DWORD,			; pointer to array
	Count:DWORD					; number of elements
;
; Writes an array of 32-bit signed decimal integers to
; standard output, separated by commas
; Receives: pointer to array, array size
; Returns: nothing
;-----------------------------------------------------------
.data
comma BYTE ", ",0
.code
	mov		esi,		pArray
	mov		ecx,		Count
	cld							; direction = forward

L1:	lodsd						; load [ESI] into EAX
	call	WriteInt			; send to output
	mov		edx,		OFFSET comma
	call	Writestring			; display comma
	loop	L1

	call	Crlf
	ret
PrintArray ENDP

END

BubbleSort.asm

TITLE  BubbleSort Procedure                  (BubbleSort.asm)

; Sort an array of signed integers, using the Bubble
; sort algorithm. The main program is in BinarySearchTest.asm.

INCLUDE Irvine32.inc

.code
	;----------------------------------------------------------
	BubbleSort PROC USES eax ecx esi,
		pArray:PTR DWORD,						; pointer to array
		Count:DWORD								; array size
	;
	; Sort an array of 32-bit signed integers in ascending order
	; using the bubble sort algorithm.
	; Receives: pointer to array, array size
	; Returns: nothing
	;-----------------------------------------------------------

		mov		ecx,	Count
		dec		ecx								; decrement count by 1

	L1:	
		push	ecx								; save outer loop count
		mov		esi,	pArray					; point to first value

	L2:	
		mov		eax,	[esi]					; get array value
		cmp		[esi+4], eax					; compare a pair of values
		jge		L3								; if [esi] <= [edi], don't exch
		xchg	 eax,	[esi+4]					; exchange the pair
		mov		[esi],	 eax

	L3:	
		add		esi,4							; move both pointers forward
		loop	L2								; inner loop

		pop	ecx									; retrieve outer loop count
		loop L1									; else repeat outer loop

	L4:	
		ret
	BubbleSort ENDP

END

BinarySearch.asm

TITLE  Binary Search Procedure            (BinarySearch.asm)

; Binary Search procedure

INCLUDE Irvine32.inc

.code
	;-------------------------------------------------------------
	BinarySearch PROC USES ebx edx esi edi,
		pArray		:PTR DWORD,				; pointer to array
		Count		:DWORD,					; array size
		searchVal	:DWORD					; search value
	LOCAL first		:DWORD,					; first position
		last		:DWORD,					; last position
		mid			:DWORD					; midpoint
	;
	; Search an array of signed integers for a single value.
	; Receives: Pointer to array, array size, search value.
	; Returns: If a match is found, EAX = the array position of the
	; matching element; otherwise, EAX = -1.
	;-------------------------------------------------------------
		mov	 first,	0						; first = 0
		mov	 eax,	Count					; last = (count - 1)
		dec	 eax
		mov	 last,	eax
		mov	 edi,	searchVal				; EDI = searchVal
		mov	 ebx,	pArray					; EBX points to the array

	L1: 
		; while first <= last
		mov	 eax,	first
		cmp	 eax,	last
		jg	 L5								; exit search

		; mid = (last + first) / 2
		mov	 eax,	last
		add	 eax,	first
		shr	 eax,	1
		mov	 mid,	eax

		; EDX = values[mid]
		mov	 esi,	mid
		shl	 esi,	2						; scale mid value by 4
		mov	 edx,	[ebx+esi]				; EDX = values[mid]

		; if ( EDX < searchval(EDI) )
		;	first = mid + 1;
		cmp	 edx,	edi
		jge	 L2
		mov	 eax,	mid						; first = mid + 1
		inc	 eax
		mov	 first,	eax
		jmp	 L4

		; else if( EDX > searchVal(EDI) )
		;	last = mid - 1;
	L2:	
		cmp	 edx,	edi
		jle	 L3
		mov	 eax,	mid						; last = mid - 1
		dec	 eax
		mov	 last,	eax
		jmp	 L4

		; else return mid
	L3:	
		mov	 eax,	mid  					; value found
		jmp	 L9								; return (mid)

	L4:	
		jmp	 L1								; continue the loop

	L5:	
		mov	 eax,-1							; search failed
	L9:	
		ret
	BinarySearch ENDP
END

BinarySearchTest.asm

TITLE Bubble Sort and Binary Search       BinarySearchTest.asm)

; Bubble sort an array of signed integers, and perform
; a binary search.
; Main module, calls Bsearch.asm, Bsort.asm, FillArry.asm

INCLUDE Irvine32.inc
INCLUDE BinarySearch.inc				; procedure prototypes

LOWVAL = -5000							; minimum value
HIGHVAL = +5000							; maximum value
ARRAY_SIZE = 50							; size of the array

.data
	array DWORD ARRAY_SIZE DUP(?)

.code
	main PROC
		call Randomize

		; Fill an array with random signed integers
		INVOKE	FillArray, ADDR array, ARRAY_SIZE, LOWVAL, HIGHVAL

		; Display the array
		INVOKE	PrintArray, ADDR array, ARRAY_SIZE
		call	WaitMsg

		; Perform a bubble sort and redisplay the array
		INVOKE	BubbleSort, ADDR array, ARRAY_SIZE
		INVOKE	PrintArray, ADDR array, ARRAY_SIZE

		; Demonstrate a binary search
		call	AskForSearchVal			; returned in EAX
		INVOKE	BinarySearch,ADDR array, ARRAY_SIZE, eax
		call	ShowResults

		call	WaitMsg;

		exit
	main ENDP



	;--------------------------------------------------------
	AskForSearchVal PROC
	;
	; Prompt the user for a signed integer.
	; Receives: nothing
	; Returns: EAX = value input by user
	;--------------------------------------------------------
	.data
	prompt BYTE "Enter a signed decimal integer "
		   BYTE "to find in the array: ",0
	.code
		call	Crlf
		mov		edx,		OFFSET prompt
		call	WriteString
		call	ReadInt
		ret
	AskForSearchVal ENDP



	;--------------------------------------------------------
	ShowResults PROC
	;
	; Display the resulting value from the binary search.
	; Receives: EAX = position number to be displayed
	; Returns: nothing
	;--------------------------------------------------------
	.data
		msg1 BYTE "The value was not found.",0
		msg2 BYTE "The value was found at position ",0
	.code
		.IF eax == -1
			mov		edx,		OFFSET msg1
			call	WriteString
		.ELSE
			mov		edx,		OFFSET msg2
			call	WriteString
			call	WriteDec
		.ENDIF
			call	Crlf
			call	Crlf
			ret
	ShowResults ENDP
END main
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值