C language classic programming 282 examples 04 search

024 Binary Search

Insert picture description here
Comic study: https://baijiahao.baidu.com/s?id=1635498997846582026&wfr=spider&for=pc
Ordered array search: Binary search:
Mini game: A thinks a number in the range [1, 1000] in my mind, B is to guess This number, if the number guessed by B is bigger than what A thinks, say it is big, if the number guessed by B is smaller than A thinks, say it is smaller, until the guess is correct.
Insert picture description here
It only takes 9 times to guess numbers within 1000. This is the idea of ​​binary search. For each guess, the median of a range of integers is selected, which is the most efficient.
Insert picture description here
Insert picture description here

If we turn the scenario into an interview question:
Find a specific integer in an ordered array of 1000 integer elements,
how should we do it?
In the same way,
we can first judge the element whose subscript is 499 (because the array subscript starts from 0 and ends at 999),
if the element is greater than the integer to be searched,
we then judge the element whose subscript is 249,
and then judge the subscript 124 elements...
and so on, until the desired element is finally found,
or the selection range is equal to 0.
The above process
is the so-called binary search algorithm, and
the time complexity of the search is log(n).

#include<stdio.h>
#include<math.h>

void binary_search(int key, int a[], int n)
{
    
    
	int low, high, mid, count = 0, count1 = 0; //count\记录查找次数,count1:记录有无查找成功!
	low = 0;
	high = n - 1;
	while (low < high)				//查找范围不为0时执行循环体语句
	{
    
    
		count++;

		mid = (low + high) / 2;
		if (key < a[mid])
		{
    
    
			high = mid - 1;
		}
		else if (key > a[mid])
		{
    
    
			low = mid + 1;
		}
		else if (key == a[mid])
		{
    
    
			printf("查找成功!\n 查找 %d 次! [%d] = %d", count, mid, key);
			count1++;
			break;
		}
	}

	if (count1 == 0)				//判断是否查找失败
	{
    
    
		printf("查找失败!\n");		//查找失败输出 no found.
	}

}

main()
{
    
    
	int a[100], i, key, n;

	printf(" 请输入数组的长度\n ");
	scanf_s("%d", &n);

	printf(" 请输入10个数据\n ");

	for (i = 1; i <= 10; i++)			//输入数组
	{
    
    
		scanf_s(" %d", &a[i]);
	}

	printf(" 请输入你想查找的元素\n ");
	scanf_s(" %d", &key);

	binary_search(key, a, n);

	printf(" \n ");
}

Basic idea:
(1) Select the record in the middle of the table, compare its keyword with the given keyword key,
——If equal, the search is successful;
——If the key value is greater than the keyword value, find the one you want If the element must be in the right sub-table, then continue to perform the half search on the right sub-table; ——If the
key value is smaller than the key value, the element you are looking for must be in the left sub-table, and continue to perform the half search in the left sub-table ,
So recursively, until the search succeeds / the search fails (the search range is 0)

025 Search by block

premise:

  • For the list of data elements that need to be searched, if there is little change or almost unchanged, we can sort this list so that we can find it later. But for a list that frequently adds data elements, if the data is sorted each time it is added, it is really a bit too tiring.

  • So for a list of almost unchanged data , 二分查找*it is good to use ** * after sorting , but for a list of frequently changing data elements , it is not a good choice to use binary search after each sorting.

① Reasons for using block search:

For a list of data elements that need to frequently increase or decrease data, sorting after each increase or decrease of data, or sorting before each search is not a good choice, which will undoubtedly increase the complexity of the search. In this case, you can use 分块查找.

②, block search structure:

  • Block search is an improved method that combines binary search and sequential search.
  • There is the concept of 索引表sum 分块in block search .
  • 索引表It is 分块a 分块basis to help search (actually an array)
    , which is used to store the maximum storage value of each block (that is, the upper limit of the range); blocking is to divide the data into several blocks through the index table.

③, small steps for block search:

  • Every time an element needs to be added,

  • First, according to the index table, know where the data should be,

  • Then add this data directly to the corresponding block, and the elements in the block do not need to be in order. Because there is no need to order in the block, the block search is especially suitable for the situation where the elements often change dynamically.

  • Block search only requires the index table to be ordered

  • When the index table is relatively large, you can perform a binary search on the index table to lock the position of the block

  • Then use sequential search for the elements in the block.

  • Although this overall performance is not better than binary search, it is much better than sequential search. The most important thing is that the sequence does not need to be completely ordered .

④ The principle of block search:

Block search requires that a
piece of data be divided into several blocks, and the elements in each block can be disordered 但是块与块之间的元素需要是有序的.
For one 非递减的数列, each element in the i-th block must be larger than any element in the i-1th block.
At the same time, block search requires one 索引表-to limit the scope of each block. It is used when adding, deleting, and searching elements.

⑤ Realization of block search:

Question: A piece of data has been divided into blocks, and there is an index table at the same time, now we want to insert an element into the data, what should we do?
Insert picture description here

  • First 插入元素, we see that the index table is 10, 20, and 30. For element 15, it should be placed in block 2. Therefore, the data of block 2 becomes 12, 18, 15, 12, 15, and 15 is inserted into the end of block 2 directly.
  • Next is 查找操作. If you want to find the number 27 in Figure 1, what should you do first? Through binary search of the index table, we find that 27 is in block 3, and then search sequentially in block 3, and get 27 in the number sequence.

Example: Use the block search method to find elements of the keyword 96 in the ordered list 11, 12, 18, 28, 39, 56, 69, 89, 96, 122, 135, 146, 156, 256, 298, and ask the user Enter the elements of the ordered list,

#include<stdio.h>
#include<math.h>

struct index
{
    
    
	int key;				//块的关键字
	int start;				//块的起始值
	int end;				//块的结束值
}index_table[4];

int block_search(int key, int a[])
{
    
    
	int i, j;
	i = 1;

	while ((i <= 3) && (key > index_table[i].key)) 		//确定在哪块中
	{
    
    
		i++;
	}

	if (i > 3)											//大于分的块数,则返回0
	{
    
    
		return 0;
	}

	j = index_table[i].start;							//确定key在哪块的起始值

	while (j <= index_table[i].end && a[j] != key) 		//在确定的块内顺序查找
	{
    
    
		j++;
	}

	if (j > index_table[i].end)							//如果大于块范围的结束值,则说明没有要查找的数,
	{
    
    
		j = 0;
	}

	return j;
}

main()
{
    
    
	int a[16], i, j = 0, key, k;


	printf(" 请输入15个数据:\n ");

	for (i = 1; i < 16; i++)			//输入数组
	{
    
    
		scanf_s("%d", &a[i]);
	}

	for (i = 1; i <= 3; i++)
	{
    
    
		index_table[i].start = j + 1;		//每个块范围的起始值
		j = j + 1;
		index_table[i].end = j + 4;			//每块范围的结束值
		j = j + 4;
		index_table[i].key = a[j];			//确定每块范围元素的最大值
	}

	printf(" 请输入你想查找的元素: \n ");
	scanf_s("%d", &key);

	k = block_search(key, a);

	if (k != 0)
	{
    
    
		printf(" 查找成功,其位置是:%d\n ", k);
	}
	else
	{
    
    
		printf(" 查找失败\n ");
	}

	printf(" \n ");


}

This example shows that 15 numbers are divided into 3 blocks according to the size of the keyword. The arrangement of these 15 numbers is an ordered sequence (or unordered), but any number in the first block must be less than the first block. All the numbers in the second block, all the numbers in the second block are less than all the numbers in the third block. When looking for an element whose key is the key, first use sequential search to find the block where the key is located in the built index table, and then search for the key in the corresponding block sequentially, if it exists, output its corresponding position, otherwise output a prompt information.

Block search is also called index search. It requires that the elements to be searched be evenly divided into blocks, and the blocks are sorted by size, and the blocks are not sorted. A block's largest (or smallest) key table, namely the index table, must be established.

026 Hash Lookup

The construction method of the hash function:

  • Digital analysis
  • Equally divide the Chinese and French
  • Segmented stacking
  • Pseudo-random number method
  • 余数法(The following examples are more commonly used)

Avoid hash collision method:

  • Open addressing method (including 线性探测再散列(more commonly used) and second detection and re-hashing)
  • Chain address
  • Rehashing
  • Establish a public overflow area

Example:
Programming to implement hash lookup. Requirements: The length of the known hash table is 11, the hash function is H(key) = key% 11, 8 elements less than 50 to be hashed are randomly generated, and 线性探测( —— When a conflict occurs, the next unit in the table is checked in order until an empty unit is found or the whole table is searched ) and then the method of hashing is used to handle the conflict. Enter the data you want to find arbitrarily, and prompt information will be given regardless of whether it is found or not.
Assuming random number: 43 23 10 25 30 28 17 21
Insert picture description here

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>


#define Max 11
#define N 8

int hashtable[Max];

int func(int value)
{
    
    
	return value % Max;					//哈希函数
}

//自定义函数实现哈希查找
int search(int key)
{
    
    
	int pos, t;
	pos = func(key);
	t = pos;

	while (hashtable[t] != key && hashtable[t] != -1)
	{
    
    
		t = (t + 1) % Max;			//利用线性探测求出下一个位置

		if (pos == t)
		{
    
    
			return -1;
		}
	}

	if (hashtable[t] == -1)
	{
    
    
		return NULL;
	}
	else
	{
    
    
		return t;
	}
}


void creathash(int key)
{
    
    
	int pos, t;
	pos = func(key);
	t = pos;

	while (hashtable[t] != -1)			//如果该位置有元素存在
	{
    
    
		t = (t + 1) % Max;
		if (pos == t) 					//如果冲突处理后确定的位置与原位置相同,则说明哈希表已经满
		{
    
    
			printf(" 哈希表已满\n ");
			return;
		}
	}
	hashtable[t] = key;
}

main()
{
    
    
	int flag[50];
	int i, j, t;

	for (i = 1; i < Max; i++)			//哈希表中,初始位置全置-1
	{
    
    
		hashtable[i] = -1;
	}

	for (i = 1; i < 50; i++)			//50以内所有数未产生时,均标志为0
	{
    
    
		flag[i] = 0;
	}

	srand((unsigned long)time(0));		//利用系统时间做种子产生随机数
	i = 0;

	while (i != N)
	{
    
    
		t = rand() % 50;				//不能产生一个50以内的随机数赋给t
		if (flag[t] == 0)				//查看是否产生t
		{
    
    
			creathash(t);				//调用函数创建哈希表
			printf("%2d: ", t);			

			for (j = 0; j < Max; j++)		
			{
    
    
				printf("(%2d)", hashtable[j]);	//输出哈希表内容
			}
				printf(" \n ");
				flag[t] = 1;			//将产生的这个数标志为1
				i++;
			
		}
	}

	printf("请输入你想要查找的元素");

	scanf_s("%d", &t);
	if (t > 0 && t < 50)
	{
    
    
		i = search(t);
		if (j != -1)
		{
    
    
			printf(" 查找成功!其位置是:%d\n ", i);
		}
		else
		{
    
    
			printf(" 查找失败!");
		}

	}
	else
		printf(" 查找有误!\n ");




}

Reference:
Binary search:
https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E5%B0%8B%E6%BC%94%E7% AE%97%E6%B3%95
https://baijiahao.baidu.com/s?id=1635498997846582026&wfr=spider&for=pc
block search:
http://data.biancheng.net/view/123.html

Guess you like

Origin blog.csdn.net/qq_41070511/article/details/110234530