Data Structure - Search (Explanation and Code Implementation of Sequential Search and Binary Search)

The concept of sequential search: starting from the other end of the table, compare the key of the record with the given value at a time. If the key of a record is equal to the given value, the search is successful, otherwise, the search fails.

ASL: average lookup length

pi lookup probability, ci lookup times

eg: sequence 1, 2, 3

The probability of finding 1 is 1/3, the probability of 2 is 1/3 twice, and the probability of 3 is 1/3 

Add up the results of the search rate of 123*the number of searches to get the average number of searches

 

Code implementation of sequential search: (here we use sequential table search) 

//顺序查找
typedef struct List
{
	int* data;//数据元素
	int* length;//数据长度
	int size;//有效数据个数
}List;

List* initList(int length)
{
	List* list = (List*)malloc(sizeof(List));
	list->length = length;
	list->data = (int*)malloc(sizeof(int) * length);
	list->size = 1;//size等于1的时候说明带有哨兵,后面的数据从第二个位置开始存元素。
	return list;
}

void listAdd(List* list,int data)
{
	if (list->size == list->length)//所存储的有效数据已经等于空间大小(空间已经满了)
{//这里我们重新定义一个newlength,防止开始length为0时,length*2=0;
	int newlength = list->length == 0 ? 4 : list->length * 2;
	int* tmp = (List*)realloc(list->data, newlength * sizeof(int));
	if (tmp == NULL)
	{
		printf("空间开辟失败\n");
		exit(-1);
	}
	else
	{
		list->data[list->size] = data;
		list->size++;
	}
	}
	else
	{
		list->data[list->size] = data;
		list->size++;
	}
}

void printlist(List* list)
{

	for ( int i = 0;  i <list->size ; i++)
	{
		printf("%d ->", list->data[i]);
	}
	printf("NULL\n");
}

int search(List* list, int key)
{
	int i=0;
	list->data[0] = key;
 //for循环后面没有语句只有分号时,当不满足for循环的条件后循环结束不再进行,直接进行下一语句。
	for (i = (list->size) - 1; list->data[i] != key; i--);//for循环后面没有语句的执行的时候需要添加分号,防止后面的语句直接进入for循环中。
	return i;//如果返回的为0则认为没有查找到,因为我们把要查找的元素放在了头节点当中。
}

int main()
{
	List* list = initList(5);
	listAdd(list, 1);
	listAdd(list, 2);
	listAdd(list, 3);
	listAdd(list, 4);
	listAdd(list, 5);
	printlist(list);
	printf("%d\n", search(list, 3));
	return 0;
}

ASL for sequential lookup: 1 time for the first node, n times for the nth node

Then the total number of searches is Sn=n*(n+1)/2 (summation formula of arithmetic sequence)

The probability of each lookup is 1/n

So the ASL for sequential search is: n*(n+1)/2*(1/n)=(n+1)/2 

So the time complexity is O(n).

Binary search L (half search):

The precondition is an ordered sequence, that is, every time the comparison starts from the middle of the sequence with the element to be searched, if the middle element is smaller than the key (the element to be searched), then search from the right of the middle element (the middle element + 1 is the first element, the tail The element remains unchanged, and then find the mid to compare with the key). Similarly, if key<mid, search from the left of mid (with the middle element -1 as the tail element, the first element remains unchanged, and compare mid with key), and return if key is equal to mid.

Code implementation: use loop search

//循环查找
int binarysearch(int key,List* list)
{
	int start = 0;
	int end = list->size - 1;
	int mid = 0;
	while (start<=end)/如果我们的首元素下标大于尾元素下标则说明我们已经遍历完整个序列不存在要找的元素
	{
		mid = (start + end) / 2;
		if (list->data[mid] < key)
		{
			start = mid + 1;
		}
		else if (list->data[mid]>key)
		{
			end = mid - 1;
		}
		else
		{
			return mid;
		}
	}
	return -1;//-1表示不存在
}

Recursive implementation of binary search:

//递归查找   1.分半2查找(左查/右查)。
int binarysearchRecursion(int key, List* list, int start, int end)
{
	//出口
	if (start == end)//每个递归都有一个终止条件相当于我们while中的start<=end,当两个下标相等时进行判断如果等于key则返回任意一个下标,如果不相等则说明没有找到
	{
		if (list->data[start]==key)
		{
			return start;
		}
		else
		{
			return -1;
		}
	}
	int mid = (start + end) / 2;
//每次查找不到进行递归,看key于mid的比较来判断如果缩小范围	
if (list->data[mid] < key)
	{
	return	binarysearchRecursion(key, list, mid+1, end);
	}
	else if (list->data[mid]>key)
	{
	return	binarysearchRecursion(key, list, start, mid - 1);
	}
	else
	{
		return mid;
	}
}

 The time complexity of binary search: (the family complexity of the two binary searches is the same, so we only explain one)

We can call the linear table a tree (because the linear table is ordered, those smaller than the key are on its coordinates, and the ones larger than it are on its right)

eg:

 Tree search: the node needs to be searched several times at which level, and the h layer needs to be searched h times (all algorithms meet this condition)

Assuming there are n nodes, h layer == "from the tree formula to get n=2^(h-1) a full binary tree.

Full binary tree: each layer has 2^(h-1) nodes

Number of searches per layer: number of nodes * number of layers == 2^(h-1)*h

ASL per layer: number of searches * probability = 1/n*2^(h-1)*h

Decompose to find 2^(h-1)*h how to use n instead

Observe that this is an arithmetic difference * geometric sequence, find the method (dislocation subtraction Sn-hSn)

3, 4 formulas at the same time: 

 

 

 

Go to × 1/n to get the ASL of the entire sequence 

 Then, when our mathematical limit n tends to be large enough, the previous fraction can be reduced, so the result

Approximately equal to: both

 

Sequential search is based on binary search. I will briefly finish the explanation. Some pictures and codes are borrowed from station b upTyrantLucifer

 

 

 

Guess you like

Origin blog.csdn.net/weixin_73612682/article/details/130873996