我的读书笔记(排序算法)
1.快速排序
- 假设待排序的序列为L[m...n],而一趟排序目的就是将其分割为两个子序列,分别为L[m...middle-1]和L[middle+1...n],其中L[m...middle-1]中的每个元素都小于L[middle],而L[middle+1...n]中的每个元素都大于L[middle]
- 递归调用快速排序算法,对L[m...middle-1]和L[middle+1..n]分别进行排序
- 由于是原地排序,所以递归结束后就自然形成了有序序列
1 /// <summary> 2 /// 快速排序算法 3 /// </summary> 4 /// <param name="data">排序数组</param> 5 /// <param name="low">排序下限</param> 6 /// <param name="high">排序上限</param> 7 static void Run(int[] data,int low, int high) 8 { 9 //简单设定中间值,并以此为一趟排序的分割点 10 //注意这里是一个简单的算法 11 //如果想对这个算法进行优化的话,可以采取随机的方法来获取分割点 12 int middle = data[(low+high)/2]; 13 int i = low; 14 int j = high; 15 do 16 { 17 //扫描middle值左边的元素 18 while (data[i] < middle && i < high) 19 i++; 20 //扫描middle值右边的元素 21 while (data[j] > middle && j > low) 22 j--; 23 //找到了一个可以交换的值 24 if (i <= j) 25 { 26 //交换 27 int temp = data[i]; 28 data[i] = data[j]; 29 data[j] = temp; 30 i++; 31 j--; 32 } 33 34 } while (i <= j); 35 //递归对比分割点元素都小的那个序列进行快速排序 36 if (j > low) 37 Run(data,low,j); 38 //递归对比分割点元素都大的那个序列进行快速排序 39 if(i<high) 40 Run(data,i,high); 41 }
快速排序在最坏的情况下运行时间为0(n*n)平均运行时间为O(nlgn),快速排序的排序对象都读入内存中,所以输入内部排序,快速排序基于比较关键字来确定元素的位置,所以它属于比较排序,同时,快速排序具有原地排序特性和不稳定特性,这意味着快速排序不需要额外的排序空间,但是不能确保相等元素位置不被交换。
2.二分法查找算法
- 在一个有序序列L[m...n]查找元素k,先比较L[(m+n)/2]的值和元素K,如果相等则返回(m+n)/2
- 如果L[(m+n)/2]的值比K小,则在L[(m+n)/2+1...n]中使用二分法查找K
- 如果L[(m+n)/2]的值比K大,则在L[m...(m+n)/2-1]中使用二分法查找K
1 static int Search(int[] data ,int val) 2 { 3 //如果数组为空,则直接返回-1 4 if (data.Length <= 0) return -1; 5 //设置初始化上下限为数组的上下限 6 int low = 0; 7 int high = data.Length - 1; 8 //循环二分法查找,直至找到或者查找完毕 9 while(low<=high) 10 { 11 //找到制定元素 12 int middle = (low + high) / 2; 13 if (data[middle] == val) 14 return middle; 15 //对二分后较大的那一半序列进行查找 16 else if (data[middle] < val) 17 low = middle + 1; 18 //对二分后较小的那一半序列进行查找 19 else 20 high = middle - 1; 21 } 22 //二分结束仍没找到指定元素 23 return -1; 24 }