二分查找
1.1定义
二分查找又称折半查找,它是一种效率较高的查找方法。
二分查找要求:线性表是有序表,即表中结点按关键字有序,并且要用向量作为表的存储结构。不妨设有序表是递增有序的。
1.2基本思想
二分查找的基本思想是:
设R[low..high]是当前的查找区间
(1)首先确定该区间的中点位置:
(2)然后将待查的K值与R[mid].key比较:若相等,则查找成功并返回此位置,否则须确定新的查找区间,继续二分查找,具体方法如下:
① 若R[mid].key>K,则由表的有序性可知R[mid..n].keys均大于K,因此若表中存在关键字等于K的结点,则该结点必定是在位置mid左边的子表R[1..mid-1]中,故新的查找区间是左子表R[1..mid-1]。
② 若R[mid].key<K,则要查找的K必在mid的右子表R[mid+1..n]中,即新的查找区间是右子表R[mid+1..n]。下一次查找是针对新的查找区间进行的。
因此,从初始的查找区间R[1..n]开始,每经过一次与当前查找区间的中点位置上的结点关键字的比较,就可确定查找是否成功,不成功则当前的查找区间就缩小一半。这一过程重复直至找到关键字为K的结点,或者直至当前的查找区间为空(即查找失败)时为止。
1.3二分查找算法
1 python 实现二分查找" 2 def find(nums,target): 3 nums.sort() 4 left=0 5 right=len(nums)-1 6 if nums[left]==target: 7 return left 8 while left<right: 9 mid=(left+right+1)/2 10 if nums[mid]==target: 11 return mid 12 if nums[mid]<target: 13 left=mid+1 14 else: 15 right=mid-1 16 return -1 17 18 if __name__=='__main__': 19 # file='a.txt' 20 # fun(file) 21 nums=[5,13,19,23,37,56,64,75,80,88,92] 22 target=92 23 s=find(nums,target) 24 print s
快速排序
快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
- 挑选基准值:从数列中挑出一个元素,称为"基准"(pivot);
- 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成;
递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
python 代码实现:
def fun(arr,left,high): i=left-1 basic=arr[high] for j in range(left,high): if arr[j]<=basic: i=i+1 arr[i],arr[j]=arr[j],arr[i] arr[i+1],arr[high]=arr[high],arr[i+1] return i+1 def quickshort(arr,low,high): if low<high: temp=fun(arr,low,high) quickshort(arr,low,temp-1) quickshort(arr,temp+1,high) if __name__=='__main__': arr = [10, 7, 8, 9, 1, 5] high=len(arr) quickshort(arr,0,high-1) print arr
冒泡排序
1.1 冒泡排序
冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
作为最简单的排序算法之一,冒泡排序给我的感觉就像 Abandon 在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。冒泡排序还有一种优化算法,就是立一个 flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来
说并没有什么太大作用。1.2 算法步骤
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
1.3 python 代码实现
def bubbling(arr): for i in range(1,len(arr)): flag=True for j in range(0,len(arr)-i): if arr[j]>arr[j+1]: arr[j],arr[j+1]=arr[j+1],arr[j] flag=False if flag==True: break return arr if __name__=='__main__': arr = [10, 7, 8, 9, 1, 5] arr=[1, 5, 7, 8, 9, 10] sort_arr=bubbling(arr) print sort_arr
选择排序
选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
1. 算法步骤
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
重复第二步,直到所有元素均排序完毕。
2.python 代码实现
def selectsort(arr): for i in range(0,len(arr)): minindex=i for j in range(i+1,len(arr)): if arr[j]<arr[minindex]: minindex=j if i!=minindex: arr[minindex],arr[i]=arr[i],arr[minindex] return arr if __name__=='__main__': arr = [10, 7, 8, 9, 1, 5] # arr=[1, 5, 7, 8, 9, 10] sort_arr=selectsort(arr) print sort_arr
插入排序
插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。
1.1 直接插入排序
直接插入排序的基本思想是:当插入第 i(i>=1)个元素时,前面的V[0],V[1],...,V[i-1]已经排好序的,这时用V[i]与V[i-1],V[i-2],...,进行比较,找到插入位置即将V[i]插入,原来位置上的元素向后顺移。
def insertsort(arr): for i in range(0,len(arr)): preindex=i-1 current=arr[i] while(preindex>=0 and arr[preindex]>current): arr[preindex+1]=arr[preindex] preindex=preindex-1 arr[preindex+1]=current return arr
1.2 折半插入排序
折半插入排序又称二分法插入排序,其基本思想是:假设V[0],V[1],...,V[i-1]是已经排好序的元素,在插入V[i]时,利用折半搜索法寻找V[i]的插入位置。
def insetsort_reduce_half(arr): for i in range(1,len(arr)): if arr[i]<arr[i-1]: temp=arr[i] left=0 right=i-1 while left<right: mid = (left + right) / 2 if arr[mid]<temp: left=mid+1 else: right=mid-1 for j in range(i-1,left-1,-1): arr[j+1]=arr[j] arr[left]=temp return arr