Algorithm: Static search algorithm

Finding is the simplest algorithm. But the search algorithm is different, there will be different gaps.

1. Search in order with sentinels.
It's very simple, let me start the code:

int[] a = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public static int findKey(int[] a, int key) {
	int index = a.length;
	while(index -- > 0) {
		if(a[index] == key)
			return index;
	}
	return -1;
}

To do this is to make two judgments (one while loop and another if statement). If there is a sentinel, we can save one judgment. We usually put the sentinel at the position of 0 in the array.
The structure of the array and the search function have changed as follows:

int key = 5;
int[] a = new int[] { key, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public static int findKey(int[] a, int key) {
	int index = a.length - 1;
	while (a[index --] == key) {
		return index;
	}
	return 0;
}

In this case, if the result of findKey returns 0, it means that the search failed, that is, there is no key value position in the array a.

2. Binary search
Binary search is based on the order of the array, that is, from large to small, or from small to large. Then the content of the array is 1 2 3 4 5 6 7 8 9 and the position where key = 8 is to be found. We can look at the algorithm implementation:

public static int findKey(int[] a, int key) {
	int low = 0;
	int high = a.length - 1;
	int middle;
	while (low <= high) {
		middle = (low + high) / 2;
		if (a[middle] == key)
			return middle;
		else if (key < a[middle])
			high = middle - 1;
		else
			low = middle + 1;
	}
	return -1;
}

In other words, if you want to find 8, low = 0, high = 8, middle = (8+0)/2=4. Because a[middle] <key, we lock 4-8 ​​and fold it in half again.
I also said at the beginning that the binary search algorithm is based on the order of the array, but the search efficiency will be high in this way. Generally speaking, when it comes to halving and recursion, the efficiency is O(log2N).

3. Block search
Block search is similar to a mixture of sequential search and binary search.
The searched array is ordered by key, and each node contains the largest key field and a pointer to the first node of the block.
The structure is as follows:

class Indetype {
	int max; // 块间最大值
	int start; // 块的起始位置
}

Write picture description here
First, you need to find the maximum value between blocks.
The size of each group is 6 is arbitrary. For better demonstration, I set the size of each group to 7. And to ensure that the minimum value of the current block is larger than the maximum value of the previous block.
First, create an index table:

class IndexType {
	int max; // 块内最大值
	int start; // 块内开始位置
}
public static int findKey(int[] a, int key) {
	int pieceCount = 0; // 计算块个数
	if (a.length % 7 == 0)
		pieceCount = a.length / 7;
	else
		pieceCount = a.length / 7 + 1;

	IndexType[] indexType = new IndexType[pieceCount]; // 初始化块数据
	for (int i = 0; i < pieceCount; i++) {
		indexType[i] = new IndexType();
		indexType[i].start = 7 * i;
	}

	for (int i = 0; i < pieceCount - 1; i++) { // 找到前pieceCount - 1块的最大值
		int max = indexType[i].start;
		for (int j = indexType[i].start; j < indexType[i + 1].start; j++) {
			if (max < a[j])
				max = a[j];
		}
		indexType[i].max = max;
	}

	int max = indexType[pieceCount - 1].start; // 找到最后一块的最大值
	for (int i = indexType[pieceCount - 1].start; i < a.length; i++) {
		if (max < a[i])
			max = a[i];
	}
	indexType[pieceCount - 1].max = max;
	
	if(key > indexType[pieceCount-1].max) // 如果大于最后一块的最大值,就返回-1
		return -1;

	// 找到key所在的块内范围,采用顺序查找
	int index = 0;
	for (index = 0; index < pieceCount - 1; index++) {
		if (indexType[index].max >= key)
			break;
	}
		
	//找到块内具体的位置,采用顺序查找
	int low = 0;
	int high = 0;
	if (index == pieceCount-1) {
		low = indexType[index].start;
		high = a.length;
	}
	else {
		low = indexType[index].start;
		high = indexType[index +1].start;
	}
	for(int i = low; i < high; i ++) {
		if(a[i] == key)
			return i;
	}
	return -1;
}

Call the above function:

int a[] = new int[] { 22, 12, 13, 8, 9, 20, 33,
	42, 44, 39, 24, 48, 60, 58,
	74, 57, 86, 53, 91, 95, 97,
	100, 98, 101
};
int key = 20;
int position = findKey(a, key);
System.out.println(position);

Guess you like

Origin blog.csdn.net/new_Aiden/article/details/50984809