1. 程式人生 > >二分法檢索(binary search)

二分法檢索(binary search)

定義:

  二分法檢索的基本思想是設字典中的元素從小到大有序地存放在陣列(array)中。首先將給定值key與字典中間位置上元素的關鍵碼(key)比較,如果相等,則檢索成功;否則,若key小,則在字典前半部分中繼續進行二分法檢索;若key大,則在字典後半部分中繼續進行二分法檢索。這樣,經過一次比較就縮小一半的檢索區間,如此進行下去,直到檢索成功或檢索失敗。偶數個取中間2個其中任何一個作為中間元素。二分法檢索是一種效率較高的檢索方法,要求字典在順序表中按關鍵碼排序。

例題:

解答:

.h:

UCLASS()
class ALGORITHM_API AAnalysisExerciseOne : public
AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AAnalysisExerciseOne(); //在陣列中尋找X,如果找到,返回True;反之,返回false; bool FindIntX(TArray<int> TargetArray, int X); //二叉法找Int bool XInArray(TArray<int> TargetArray, int LeftIndex, int
RightIndex, int X, bool IncreaseSide); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; public: // Called every frame virtual void Tick(float DeltaTime) override; private: TArray<int> RawArray; }; .cpp: // Sets default values
AAnalysisExerciseOne::AAnalysisExerciseOne() { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; } //在陣列中尋找X,如果找到,返回True;反之,返回false; bool AAnalysisExerciseOne::FindIntX(TArray<int> TargetArray, int X) { //利用二叉法,尋找遞增陣列和遞減陣列的共用元素 //左右兩個點 int Left(0); int Right(TargetArray.Num()); //這個是要找的元素的index int TargetInt(0); //開始尋找 while (Left <= Right) { //找中間點,如果有小數點,捨棄,取整 int Mid = Left + (Right - Left) / 2; if (TargetArray[Mid - 1] < TargetArray[Mid] && TargetArray[Mid]>TargetArray[Mid + 1]) { //找到了,結束While TargetInt = Mid; break; } else if (TargetArray[Mid - 1] < TargetArray[Mid]) { Left = Mid + 1; } else if (TargetArray[Mid] > TargetArray[Mid + 1]) { Right = Mid - 1; } //在雙調陣列中,TargetArray[Mid - 1] > TargetArray[Mid] && TargetArray[Mid] < TargetArray[Mid + 1]的情況不存在 else break; } //等於0說明沒找到,出問題了,返回 if (TargetInt == 0) return false; //X比陣列中所有數字都大,X不在陣列中 if (X > TargetArray[TargetInt]) return false; if (X == TargetArray[TargetInt]) return true; //先在增長陣列中找 if (XInArray(TargetArray, 0, TargetInt - 1, X, true)) { UKismetSystemLibrary::PrintString(this, "Find in increase side!"); return true; } //如果在增長陣列中找不到,則去減少陣列中找 else { if (XInArray(TargetArray, TargetInt + 1, TargetArray.Num() - 1, X, false)) { UKismetSystemLibrary::PrintString(this, "Find in Decrease side!"); return true; } //都找不到,說明沒有 else { UKismetSystemLibrary::PrintString(this, "Don't Find it!"); return false; } } } bool AAnalysisExerciseOne::XInArray(TArray<int> TargetArray, int LeftIndex, int RightIndex, int X, bool IncreaseSide) { int Left(LeftIndex); int Right(RightIndex); //開始尋找 if (IncreaseSide) { //在遞增區域中尋找 while (Left <= Right) { //找中間點,如果有小數點,捨棄,取整 int Mid = Left + (Right - Left) / 2; if (X < TargetArray[Mid]) { Right = Mid - 1; } else if (X > TargetArray[Mid]) { Left = Mid + 1; } else return true; } return false; } //在遞減區域中尋找 else { while (Left <= Right) { //找中間點,如果有小數點,捨棄,取整 int Mid = Left + (Right - Left) / 2; if (X > TargetArray[Mid]) { Right = Mid - 1; } else if (X < TargetArray[Mid]) { Left = Mid + 1; } else return true; } return false; } } // Called when the game starts or when spawned void AAnalysisExerciseOne::BeginPlay() { Super::BeginPlay();
   //測試
//給定一個初始陣列 RawArray.Add(1); RawArray.Add(3); RawArray.Add(5); RawArray.Add(7); RawArray.Add(6); RawArray.Add(4); RawArray.Add(2); RawArray.Add(0); RawArray.Add(-2); RawArray.Add(-4); RawArray.Add(-6); RawArray.Add(-10); if (FindIntX(RawArray, -10)) { UKismetSystemLibrary::PrintString(this, "Find it!"); } else { UKismetSystemLibrary::PrintString(this, "Don't Find it!"); } } // Called every frame void AAnalysisExerciseOne::Tick(float DeltaTime) { Super::Tick(DeltaTime); }