Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

ค้นหาไบนารี Java:A Guide

วิธีการเขียนอัลกอริทึมการค้นหาแบบไบนารีใน Java

คอมพิวเตอร์ไม่ค้นหาสิ่งของเหมือนที่มนุษย์ทำ ในขณะที่มนุษย์สามารถเปลี่ยนวิธีการในการค้นหาบางสิ่งได้ คอมพิวเตอร์จำเป็นต้องได้รับคำแนะนำเฉพาะเกี่ยวกับการค้นหารายการใดรายการหนึ่ง นั่นคือสิ่งที่อัลกอริธึมมาตรฐานมีประโยชน์

การค้นหาไบนารีเป็นตัวอย่างของอัลกอริธึมมาตรฐาน ใช้เพื่อค้นหาองค์ประกอบในอาร์เรย์ของรายการ ในคู่มือนี้ เราจะพูดถึงการค้นหาไบนารีคืออะไร วิธีทำงาน และวิธีที่คุณสามารถนำไปใช้ใน Java เราจะพูดถึงสองตัวอย่างของการค้นหาแบบไบนารี:แบบหนึ่งใช้วิธีการแบบเรียกซ้ำ และอีกแบบใช้วิธีการแบบวนซ้ำ

เริ่มกันเลย!

การค้นหาแบบไบนารีคืออะไร

การค้นหาแบบไบนารีคืออัลกอริธึมการค้นหาที่กำหนดตำแหน่งขององค์ประกอบในอาร์เรย์ที่เรียงลำดับ

การค้นหาไบนารีเริ่มต้นด้วยการแบ่งรายการออกเป็นสองส่วน การค้นหาจะเปรียบเทียบตัวเลขตรงกลางกับตัวเลขที่อัลกอริทึมกำลังค้นหา

ถ้าตัวเลขน้อยกว่าตัวเลขตรงกลาง กระบวนการนี้จะทำซ้ำสำหรับครึ่งล่างของรายการ มิฉะนั้น กระบวนการนี้จะทำซ้ำสำหรับครึ่งบนของรายการ

การค้นหาแบบไบนารีมีประสิทธิภาพมากกว่าการค้นหาเชิงเส้น ซึ่งเป็นการค้นหาทั่วไปอีกประเภทหนึ่ง เนื่องจากทุกครั้งที่อัลกอริทึมค้นหารายการ จะลดจำนวนรายการที่ต้องการค้นหาลงเป็นสองเท่า

การค้นหาแบบไบนารีสามารถดำเนินการได้เฉพาะในรายการที่เรียงลำดับแล้วเท่านั้น ซึ่งหมายความว่าหากคุณยังไม่มีรายการที่จัดเรียง คุณจะต้องจัดเรียงโดยใช้อัลกอริทึมการจัดเรียงก่อนที่จะดำเนินการค้นหาแบบไบนารี

81% ของผู้เข้าร่วมกล่าวว่าพวกเขารู้สึกมั่นใจมากขึ้นเกี่ยวกับโอกาสในการทำงานด้านเทคโนโลยีหลังจากเข้าร่วม bootcamp จับคู่กับ Bootcamp วันนี้

ผู้สำเร็จการศึกษาจากหลักสูตร bootcamp โดยเฉลี่ยใช้เวลาน้อยกว่าหกเดือนในการเปลี่ยนอาชีพ ตั้งแต่เริ่มต้น bootcamp ไปจนถึงหางานแรก

การค้นหาไบนารีทำงานอย่างไร

การค้นหาไบนารีสามารถทำได้สองวิธี:วนซ้ำหรือวนซ้ำ

การค้นหาไบนารีแบบวนซ้ำเป็นการค้นหาแบบวนซ้ำเพื่อค้นหารายการในรายการ การค้นหาไบนารีแบบเรียกซ้ำใช้ฟังก์ชันที่เรียกตัวเองซ้ำแล้วซ้ำอีกเพื่อค้นหารายการในรายการ การค้นหาไบนารีแบบเรียกซ้ำใช้วิธีการแบ่งและพิชิตเพื่อค้นหารายการ

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการเรียกซ้ำในคู่มือการเรียกซ้ำของ Java

อัลกอริทึมทั่วไปสำหรับการดำเนินการค้นหาแบบไบนารีจะเหมือนกันไม่ว่าคุณจะตัดสินใจใช้แนวทางใด

พิจารณารายการต่อไปนี้:

6 7 8 9 10

เราจะค้นหาหมายเลข 7 ในรายการของเรา ในการเริ่มต้น เราจะตั้งค่าตัวชี้สองตัวซึ่งแสดงถึงตำแหน่งต่ำสุดและสูงสุดในรายการของเรา:

ต่ำ


สูง
6 7 8 9 10

ต่อไปเราต้องหาองค์ประกอบกลางในอาร์เรย์ของเรา เราสามารถทำได้โดยใช้สูตร:(ต่ำ + สูง) / 2 ในกรณีนี้องค์ประกอบตรงกลางคือ 8

อัลกอริทึมของเราจะเปรียบเทียบว่าองค์ประกอบตรงกลางเท่ากับองค์ประกอบที่เรากำลังค้นหาหรือไม่ หากตัวเลขเท่ากัน การค้นหาของเราจะหยุดลง เรากำลังมองหาหมายเลข 7 ซึ่งไม่เท่ากับ 8 ดังนั้นการค้นหาของเราจึงดำเนินต่อไป

อัลกอริทึมของเราจะเปรียบเทียบว่าจำนวนที่เรากำลังค้นหานั้นมากกว่าตัวเลขตรงกลางหรือไม่ ถ้ามากกว่านั้น การค้นหาของเราจะเริ่มต้นใหม่อีกครั้งในครึ่งบนของรายการ ทำได้โดยการตั้งค่า low ให้เท่ากับ low =middle_number + 1 มิฉะนั้น การค้นหาจะเริ่มต้นอีกครั้งที่ครึ่งล่างของรายการ

7 (ตัวเลขที่เรากำลังค้นหา) ไม่เกิน 8 (ตัวเลขกลาง) ซึ่งหมายความว่าอัลกอริทึมของเรากำลังค้นหาในช่วงครึ่งล่างของรายการ เราทำสิ่งนี้โดยตั้งค่า “สูง” เป็น high =middle_number – 1

ต่ำ กลาง สูง

6 7 8 9 10

ตอนนี้ อัลกอริทึมของเรากำลังจะทำการค้นหาซ้ำ เราจะเปรียบเทียบตัวเลขตรงกลาง 7 กับตัวเลขที่เรากำลังค้นหา เรากำลังมองหาหมายเลข 7 ดังนั้นอัลกอริทึมการค้นหาของเราจึงหยุดลง เราพบตำแหน่ง 7 ในรายการของเราแล้ว!

วิธีการใช้ Java Binary Search

เราเลิกใช้ทฤษฎีนี้แล้ว ตอนนี้เหลือเพียงดำเนินการค้นหาของเรา เป็นสิ่งหนึ่งที่ต้องผ่านและค้นหารายการด้วยตัวเราเอง การเขียนโค้ดอัลกอริธึมที่ทำการค้นหาเราเป็นอีกสิ่งหนึ่งที่ทั้งหมด

เราจะเริ่มต้นด้วยการเขียนโปรแกรมที่ใช้การค้นหาไบนารี Java โดยใช้วิธีการวนซ้ำ

วิธีการทำซ้ำ

มากำหนดฟังก์ชันที่เรียกว่า searchItems ซึ่งค้นหาผ่านรายการของเรา:

class BinarySearch {
	int searchItems(int array[], int searchingFor, int low, int high) {
		while (low <= high) {
			int middle = low + (high - low) / 2;

			if (array[middle] == searchingFor) {
				return middle;
			} else if (array[middle] < searchingFor) {
				low = middle + 1;
			} else {
				high = middle - 1;
			}
		}
		return -1;
	}
}

ฟังก์ชันนี้จะค้นหารายการของเราโดยใช้การค้นหาแบบไบนารี

ฟังก์ชันของเรายอมรับพารามิเตอร์สี่ตัว ได้แก่ รายการที่เราต้องการค้นหา (อาร์เรย์) รายการที่เรากำลังค้นหา (กำลังค้นหา) ตัวเลขต่ำ (ต่ำ) และตัวเลขสูง (สูง)

ภายในฟังก์ชันของเราเราได้ประกาศ while loop แม้ว่าค่าของ "ต่ำ" จะน้อยกว่าหรือเท่ากับ "สูง" การวนซ้ำจะดำเนินการ

วง while ของเราเริ่มต้นด้วยการคำนวณจำนวนตรงกลาง จากนั้นจะตรวจสอบเพื่อดูว่าค่าที่ตำแหน่งนั้นเท่ากับค่าที่เรากำลังค้นหาหรือไม่

หากตัวเลขเหล่านั้นเท่ากัน ค่านั้นจะถูกส่งคืนไปยังโปรแกรมหลักของเรา หากไม่เป็นเช่นนั้น โปรแกรมของเราจะตรวจสอบว่าค่าที่ตำแหน่งตรงกลางน้อยกว่าค่าที่เรากำลังค้นหาหรือไม่ ถ้าใช่ ค่าต่ำใหม่จะถูกตั้งค่า

มิฉะนั้น ค่าสูงใหม่จะถูกตั้งค่าเพื่อให้รายการของเราสามารถค้นหาได้อีกครั้งในครึ่งบนของรายการ

หากไม่พบรายการของเรา -1 จะถูกส่งคืน เราจะใช้สิ่งนี้เพื่อบอกโปรแกรมหลักของเราว่าไม่พบรายการในหนึ่งนาที

รหัสของเราไม่ได้ทำอะไรเลยเพราะเรายังไม่ได้เขียนโปรแกรมหลักของเรา เพิ่มโค้ดต่อไปนี้ใต้ searchItems() ฟังก์ชันในคลาส BinarySearch ของคุณ:

public static void main(String args[]) {
		BinarySearch newSearch = new BinarySearch();

		int listToSearch[] = { 6, 7, 8, 9, 10 };
		int listLength = listToSearch.length;
		int numberToFind = 7;

		int findNumber = newSearch.searchItems(listToSearch, numberToFind, 0, listLength - 1);

		if (findNumber != -1) {
			System.out.println(numberToFind + " was found at index position " + findNumber + ".");
		} else {
			System.out.println(numberToFind + " was not found in the list.");
		}
	}

เรียกใช้โค้ดของเราแล้วดูว่าเกิดอะไรขึ้น:

7 was found at index position 1.

We've found the position of our number!

โปรแกรมหลักของเราเริ่มต้นด้วยการเริ่มต้นอินสแตนซ์ของคลาส BinarySearch เราใช้สิ่งนี้เพื่อเริ่มการค้นหาของเราในโปรแกรม จากนั้นเราจะกำหนดตัวแปรสามตัว:

  • listToSearch:รายการที่เราต้องการค้นหา
  • listLength:ความยาวของรายการ
  • numberToFind:หมายเลขที่เรากำลังมองหาในรายการ

เมื่อเรากำหนดตัวแปรเหล่านี้แล้ว เราจะใช้ searchItems() ฟังก์ชั่นที่เราประกาศไว้ก่อนหน้านี้เพื่อค้นหาตัวเลขในรายการของเรา เรากำหนดค่าที่ฟังก์ชันนี้จะส่งคืนให้กับตัวแปร "findNumber"

หาก findNumber ไม่เท่ากับ -1 ซึ่งหมายความว่าพบหมายเลขของเราแล้ว ตำแหน่งดัชนีของรายการที่เรากำลังค้นหาจะถูกพิมพ์ไปยังคอนโซล มิฉะนั้น จะมีการพิมพ์ข้อความไปที่คอนโซลเพื่อแจ้งว่าไม่พบหมายเลข

วิธีการแบบเรียกซ้ำ

สามารถใช้วิธีการแบบเรียกซ้ำเพื่อใช้การค้นหาแบบไบนารี นี่คือที่ที่คุณเขียนฟังก์ชันที่เรียกตัวเองจนกว่าจะพบรายการที่ระบุ

เริ่มต้นด้วยการกำหนดฟังก์ชันที่ทำการค้นหาไบนารีของเราแบบเรียกซ้ำ:

class BinarySearch {
	int searchItems(int array[], int searchingFor, int low, int high) {
		if (high >= low) {
			int middle = low + (high - low) / 2;
	
if (array[middle] == searchingFor) {
				return middle;
			} else if (array[middle] < searchingFor) {
				searchItems(array, searchingFor, middle + 1, high);
			} else {
				searchItems(array, searchingFor, low, middle - 1);
			}
		}
		return -1;
	}
}

ฟังก์ชันนี้ใช้การค้นหาไบนารีของเราในทางที่ต่างออกไป แทนที่จะใช้ while loop เราใช้ if คำสั่งตรวจสอบว่าจำนวนสูงเท่ากับหรือน้อยกว่าจำนวนที่ต่ำ

หากข้อความนี้ประเมินว่าเป็นจริง การค้นหาของเราจะเริ่มต้นขึ้น มิฉะนั้น -1 จะถูกส่งกลับ ซึ่งบอกโปรแกรมของเราว่าไม่พบรายการที่ระบุในรายการ

ภายใน if . ของเรา คำสั่งเราตรวจสอบว่าค่าของตัวเลขตรงกลางเท่ากับค่าที่เรากำลังค้นหาหรือไม่ ถ้าใช่ เราจะคืนหมายเลขนั้นไปที่โปรแกรมหลักของเรา

หากข้อความนี้ไม่ประเมินว่าเป็นจริง โปรแกรมของเราจะตรวจสอบเพื่อดูว่าตัวเลขที่อยู่ตรงกลางน้อยกว่าตัวเลขที่เรากำลังค้นหาหรือไม่ ถ้าใช่ searchItems() เมธอดจะถูกรันอีกครั้ง แต่คราวนี้จำนวนที่ต่ำของเราจะเท่ากับหนึ่งที่มากกว่าจำนวนตรงกลางของเรา สิ่งนี้จะแบ่งจำนวนรายการที่เราต้องการค้นหาออกเป็นสองส่วน

มิฉะนั้น searchItems() ถูกเรียกใช้อีกครั้งและค่าของจำนวนสูงสุดจะเท่ากับจำนวนตรงกลางลบหนึ่ง ซึ่งหมายความว่าเราสามารถปรับแต่งการค้นหาของเราได้เพียงครึ่งซ้ายของรายการของเรา

เราสามารถใช้ฟังก์ชันหลักเดียวกันกับที่เราเขียนไว้ก่อนหน้านี้เพื่อทดสอบโค้ดของเรา มาดูกันว่าจะเกิดอะไรขึ้นเมื่อเรารันโค้ดของเรา:

7 was found at index position 1.

พบสินค้าของเราอีกแล้ว! ครั้งนี้ เราใช้วิธีการแบบเรียกซ้ำเพื่อค้นหาหมายเลขของเราแทนการวนซ้ำ

การวิเคราะห์ความซับซ้อน

อัลกอริธึมการค้นหาแบบไบนารีมีความซับซ้อนของตัวพิมพ์ที่ดีที่สุดของ O(1) สิ่งนี้จะเกิดขึ้นเมื่อรายการแรกที่เปรียบเทียบโดยอัลกอริทึมคือรายการที่มีการค้นหา

อัลกอริธึมการค้นหาแบบไบนารีมีความซับซ้อนของตัวพิมพ์ใหญ่และตัวพิมพ์เล็กโดยเฉลี่ยของ O(log n) ซึ่งหมายความว่า ในกรณีส่วนใหญ่ และในกรณีที่เลวร้ายที่สุด ความเร็วของอัลกอริทึมจะช้าลงตามลอการิทึม ขึ้นอยู่กับจำนวนรายการที่ต้องทำการค้นหา

บทสรุป

การค้นหาไบนารีใช้เพื่อค้นหาตำแหน่งขององค์ประกอบในรายการที่เรียงลำดับ การค้นหาแบบไบนารีจะเปรียบเทียบรายการที่อยู่ตรงกลางส่วนของอาร์เรย์กับตัวเลขที่อัลกอริทึมกำลังค้นหา

การค้นหาไบนารีมีประสิทธิภาพมากกว่าการค้นหาเชิงเส้น เนื่องจากทุกครั้งที่ทำการค้นหา จำนวนค่าที่ต้องค้นหาจะถูกหารด้วยสองค่า

ตอนนี้คุณพร้อมแล้วที่จะใช้การค้นหาไบนารีใน Java เหมือนกับโปรแกรมเมอร์ผู้เชี่ยวชาญ