s11d27 算法

s11d27 算法

一、理论

1.1 时间复杂度和空间复杂度的理论:

1)空间复杂度:

是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,

简单说就是递归集算时通常是反复调用同一个方法,递归n次,就需要n个空间。

2)时间复杂度

一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。

算法的基本操作重复执行的次数是模块n的某一个函数f(n),因此,算法的时间复杂度记做:T(n)=O(f(n))。

随着模块n的增大,算法执行的时间的增长率和f(n)的增长率成正比,所以f(n)越小,算法的时间复杂度越低,算法的效率越高。

1.2 函数调用的时间复杂度分析

按数量级递增排列,常见的时间复杂度有:

常数阶O(1),  对数阶O(log2n),  线性阶O(n),  线性对数阶O(nlog2n),  平方阶O(n^2), 立方阶O(n^3),..., k次方阶O(n^k), 指数阶O(2^n)

常用的时间复杂度所耗费的时间从小到大依次是:O(1)<O(log2n)<O(n)<O(nlog2n)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)

常用的算法的时间复杂度和空间复杂度


排序法


平均时间复杂度


说明


稳定度


空间复杂度


备注


冒泡排序


O(n2)


将待排序的元素看作是竖着排列的“气泡”,较小的元素比较轻,从而要往上浮


稳定


O(1)


快速排序


O(n*log2n)


先选择中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(递归)。


不稳定


O(log2n)~O(n) 因为用到了递归!


选择排序


O(n2)


首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此递归。


稳定


O(1)


插入排序


O(n2)


逐一取出元素,在已经排序的元素序列中从后向前扫描,放到适当的位置


稳定


O(1)


起初,已经排序的元素序列为空


堆排序


O(n*log2n)


利用堆(heaps)这种数据结构来构造的一种排序算法。堆是一个近似完全二叉树结构,并同时满足堆属性:即子节点的键值或索引总是小于(或者大于)它的父节点。


不稳定


O(1)


近似完全二叉树


希尔排序


O


选择一个步长(Step) ,然后按间隔为步长的单元进行排序.递归,步长逐渐变小,直至为1.


不稳定


O(1)


箱排序


O(n)


设置若干个箱子,把关键字等于 k 的记录全都装入到第k 个箱子里 ( 分配 ) ,然后按序号依次将各非空的箱子首尾连接起来 ( 收集 ) 。


O(1)


分配排序的一种:通过" 分配 " 和 " 收集 " 过程来实现排序。

当一个算法的空间复杂度为一个常量,即不随被处理数据量n的大小而改变时,可表示为O(1)

访问数组中的元素是常数时间操作,一个算法如果能在每个步骤去掉一半数据元素,如二分检索,通常它就取 O(logn)时间。

二、查找算法

2.1 两分法

aList = [1, 2, 3, 4, 5, 6, 7, 8]

def binarySearch(aList, t):

low = 0

heigh = len(aList) - 1

while low <= heigh:     # 这里为了防止,low=height然后不进入程序,return正确的情况,如:t=3,low=heigh=2

mid = (low + heigh) / 2

print ‘mid:‘,mid

if t > aList[mid]:

low = mid + 1

elif t < aList[mid]:

heigh = mid - 1

else:

print "索引,值:",mid,aList[mid]

return mid  # 返回索引值

print ‘low:‘,low

print ‘heigh:‘,heigh

return -1       # 为了防止元素找不到的情况,就返回-1

print binarySearch(aList,2)

三、排序算法

3.1 冒泡排序

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘

import random
import time

‘‘‘
aList=[]
for i in range(20):
    aList.append(random.randrange(100))
print aList
‘‘‘
aList=[]
for i in range(50000):
    aList.append(random.randrange(100000))

def bubble_sort(aList):# 例如 aList的个数是10个
    for i in range(len(aList)): # 循环索引 0-9
        for j in range(len(aList)-i-1):    # 第一次循环索引j为:8,这里为啥要-1,因为下面会有j+1
            if aList[j]>aList[j+1]:
                temp=aList[j+1]
                aList[j+1]=aList[j]
                aList[j] = temp
    return aList

start_time=time.time()
print bubble_sort(aList)[0:20]
end_time=time.time()
print end_time-start_time

# 给5万个数排序,282秒

3.2 选择排序

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘

import random
import time

‘‘‘
aList=[]
for i in range(20):
    aList.append(random.randrange(100))
print aList
‘‘‘
aList=[]
for i in range(50000):
    aList.append(random.randrange(100000))

#print aList

def select_sort(aList):
    for i in range(len(aList)):
        for j in range(i,len(aList)):
            if aList[i]>aList[j]:
                temp = aList[i]
                aList[i]= aList[j]
                aList[j]= temp
    return aList

start_time=time.time()
print select_sort(aList)[0:20]
end_time=time.time()
print end_time-start_time

‘‘‘
第一层循环是循环整个列表
第二层是从i开始循环,到列表结尾。
如果找到比aList[i]小的元素,就和aList[i]交换。
和冒泡算法的时间和空间复杂度基本是一样的。区别是:
1)冒泡算法是两两交换,循环交换的结果把最大的数依次放在最后面。
2)选择排序是把当前的数和aList[i],循环结果就是把最小的数依次放在前面。
# 给5万个数排序,225秒
‘‘‘

3.3 直接插入排序

插入排序(Insertion Sort)的基本思想是:将列表分为2部分,左边为排序好的部分,右边为未排序的部分,循环整个列表,每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘

import random
import time

‘‘‘
aList=[]
for i in range(20):
    aList.append(random.randrange(100))
print aList
‘‘‘
‘‘‘
插入排序,是已经有一个已排序列表,索引是:0到i-1,靠向右移动一个位置,腾出一个空位来插入当前值。
详细:
由于插入排序是:通过从索引“0到i-1”已经排好序的列表中,由iCur(aList[i])去从跟从i-1,一直旺座不停的比对,一直到<某个元素,
就插入到某个元素的前面。其实就是顺序查找插入,时间复杂度;O(n)。
注意:这里不可能改变列表的个数,当然更不能用insert语句了。
那怎么保持原列表不变,从已经排好序的列表里(0到i-1),插入一个数呢?
就通过:
如果iCur的左边的紧靠的元素比它大,要把左边的元素一个一个的往右移一位,
直到iCur比aList[position-1]小,iCur插入到左边挪一个位置出来
也就是靠向右移动位置,给icur腾出一个空位,以便插入!
‘‘‘

aList=[]
for i in range(50000):
    aList.append(random.randrange(100000))

def insert_sort(aList):
    for i in range(1,len(aList)):   # 默认列表第一个已经排好序了
        iCur= aList[i]
        position=i
        while position>0 and iCur<aList[position-1]:
            aList[position]=aList[position-1]
            position-=1
        aList[position]=iCur
    return aList

start_time=time.time()
print insert_sort(aList)[0:20]
end_time=time.time()
print end_time-start_time

‘‘‘
# 给5万个数排序,149秒
‘‘‘

四、快速排序

设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动  

注:在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的;若具有相同关键字的记录之间的相对次序发生改变,则称这种排序方法是不稳定的。

要注意的是,排序算法的稳定性是针对所有输入实例而言的。即在所有可能的输入实例中,只要有一个实例使得算法不满足稳定性要求,则该排序算法就是不稳定的。

4.1 快速排序--清爽代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘

def quick_sort(aList, left, right):
    if left >= right:
        return
    low = left
    high = right
    k = aList[left]
    while low < high:
        while high > 0 and low != high and aList[low] <= aList[high]:
            high -= 1
        temp = aList[low]
        aList[low] = aList[high]
        aList[high] = temp

while low != high and aList[high] > aList[low]:
            low += 1
        temp = aList[high]
        aList[high] = aList[low]
        aList[low] = temp
    quick_sort(aList, left, low - 1)
    quick_sort(aList, low + 1, right)

aList = [83, 83, 94, 51, 9, 79, 40, 68, 12, 17]

print aList
quick_sort(aList, 0, len(aList) - 1)
print aList

‘‘‘
打印结果:
[83, 83, 94, 51, 9, 79, 40, 68, 12, 17]
[9, 12, 17, 40, 51, 68, 79, 83, 83, 94]
‘‘‘

4.2 快速排序-错误示范讲解

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘
import random
‘‘‘
aList=[6,2,5,11,3,8,9]
6,2,5,11,3,8,9  current_val=6 索引:low=0,high=6 初始值
此时算hight的:从后往前,跟6比大小,high的索引递减,这里递减了2次,注意:直到遇见比6小的,才交换位置。
3,2,5,11,6,8,9  current_val=6 索引:low=0,high=4
此时算low的:从前往后,跟6比大小,low的索引递增,这里递增了3次,注意:直到遇见比6大的,才交换位置。
3,2,5,6,11,8,9  current_val=6 索引:low=3,high=4
此时算hight的:从后往前,因为11比6大,high的索引-1=3,不交换位置。此时:low=high=6,
这是第一次排序,把比6小的发在6的左边,把比6大的放在6的右边。
3,2,5,6,11,8,9  current_val=6 索引:low=3,high=3

开始第二次排序,先排序6的左边:此时6的位置已经固定,不需要排它了!
注意:此时low和high的索引还是针对完整列表(第一次排序好的列表:
[3,2,5,6,11,8,9])来说的。因为是给aList排序,不是给[3,2,5]排序!
3,2,5           current_val=3 索引:low=0,high=2  初始值
2,3,5           current_val=3 索引:low=0,high=1  从后向前,交换
2,3,5           current_val=3 索引:low=1,high=1  不交换

开始第三次排序,排6的右边:此时6的位置已经固定,不需要排它了!
注意:此时low和high的索引还是针对第二次排序好的列表:
[2,3,5,6,11,8,9])来说的。
11,8,9          current_val=11 索引:low=4,high=6 初始值
9,8,11          current_val=11 索引:low=4,high=5 从后向前,交换
8,9,11          current_val=11 索引:low=5,high=5 从前向后,交换

第三次排序好的列表,就是最终结果,因为左边列表 和右边的列表,都分别得到了一个值。
最终结果:
[2,3,5,6,8,9,11]
‘‘‘

def quick_sort(aList, left,right):  # left 和right是为了递归用的。
    # if low==high and low>0:
    if left>=right:
        return
    low=left            # 这两句是为了递归用的
    high= right
    k = aList[left]     # 定的固定值,以它为标杆排序
    while low<high:
        # print ‘aList[low]:‘,aList[low]
        # print ‘aList[high]:‘,aList[high]
        # print ‘low:‘,low
        # print ‘high:‘,high
        print aList

# while high>0 and low!=high and aList[low]<=aList[high]: # 此时 aList[low]是关键字,递归low的值。这是对的
        ‘‘‘
        注意:这里high是递减的,可能high会减成负数,会报错,所以high>0
        high是递减的,如果high减的跟low相等了,不应该再执行,结果再执行high-=1,则high<low,结果错误的交换了!

如下所示:
        [9, 12, 51, 17, 40, 68, 79, 83, 94, 83]
        low1: 5
        high1: 5
        low2: 5
        high2: 4
        [9, 12, 51, 17, 68, 40, 79, 83, 94, 83]

所以,这里应该写成:
        while high>0 and low!=high and aList[low]<=aList[high]:
        或者直接写成:
        while low<high and aList[low]<=aList[high]:
        ‘‘‘
        # 有时候有多个相同的元素,所以要写成<=
        while high>0 and aList[low]<=aList[high]: # 此时 aList[low]是关键字,递归low的值。应该加上条件:and low!=high

# while high>0 and k<=aList[high]:    # 这样写也是对的,关键字就是k。这时候k就是aList[low]
            if low==high:
                print ‘low1:‘,low
                print ‘high1:‘,high
            high-=1
        print ‘low2:‘,low
        print ‘high2:‘,high
        temp=aList[low]         # 其实是low和high之间互换位置。
        aList[low]= aList[high]
        aList[high]=temp
        print aList
        #print ‘sec_aList[low]:‘,aList[low]
        #print ‘sec_aList[high]:‘,aList[high]
        # 因为low和high是互相变动的,有的时候low是关键字,有的时候high是关键字,有的时候low=high=关键字
        # 而每次while循环,都只针对一个固定值,小的放左边,大的放右边

‘‘‘
        这里也一样,如果low+=1的话,low和high相等的时候(本来不应该执行了),low再加1,则又做了错误的交换了。
        ‘‘‘
        # while low!=high and aList[high]>aList[low]:   # 此时 aList[high]是关键字,递归low的值 是对的
        while aList[high]>aList[low]:   # 此时 aList[high]是关键字,递归low的值 ,应该加上条件:andand low!=high
        # while k>aList[low]: # 这样写也是对的,关键字就是k。这时候k就是aList[high]
            if low==high:
                print ‘low3:‘,low
                print ‘high3:‘,high
            low+=1
        temp=aList[high]
        aList[high]= aList[low]
        aList[low]=temp

#print ‘result:‘,aList
    # if low==high and low>0:
    # quick_sort(aList, 0,low-1)
    #print ‘left:‘,left
    #print ‘low-1:‘,low-1
    # quick_sort(aList, 0,low-1)
    quick_sort(aList, left,low-1)
    # quick_sort(aList, low+1,len(aList)-1)
    quick_sort(aList, low+1,right)

#print aList

‘‘‘
aList=[]
for i in range(20):
    aList.append(random.randrange(100))
print aList

aList=[6,2,5,11,3,8,9]

aList=[]
for i in range(10):
    aList.append(random.randrange(100))
‘‘‘

aList=[83, 83, 94, 51, 9, 79, 40, 68, 12, 17]
# aList=[83, 83, 94, 51, 9, 79, 40]
print aList
quick_sort(aList, 0,len(aList)-1)
print aList

4.3 快速排序--正确

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ‘WangQiaomei‘
import random
‘‘‘
aList=[6,2,5,11,3,8,9]
6,2,5,11,3,8,9  current_val=6 索引:low=0,high=6 初始值
此时算hight的:从后往前,跟6比大小,high的索引递减,这里递减了2次,注意:直到遇见比6小的,才交换位置。
3,2,5,11,6,8,9  current_val=6 索引:low=0,high=4
此时算low的:从前往后,跟6比大小,low的索引递增,这里递增了3次,注意:直到遇见比6大的,才交换位置。
3,2,5,6,11,8,9  current_val=6 索引:low=3,high=4
此时算hight的:从后往前,因为11比6大,high的索引-1=3,不交换位置。此时:low=high=6,
这是第一次排序,把比6小的发在6的左边,把比6大的放在6的右边。
3,2,5,6,11,8,9  current_val=6 索引:low=3,high=3

开始第二次排序,先排序6的左边:此时6的位置已经固定,不需要排它了!
注意:此时low和high的索引还是针对完整列表(第一次排序好的列表:
[3,2,5,6,11,8,9])来说的。因为是给aList排序,不是给[3,2,5]排序!
3,2,5           current_val=3 索引:low=0,high=2  初始值
2,3,5           current_val=3 索引:low=0,high=1  从后向前,交换
2,3,5           current_val=3 索引:low=1,high=1  不交换

开始第三次排序,排6的右边:此时6的位置已经固定,不需要排它了!
注意:此时low和high的索引还是针对第二次排序好的列表:
[2,3,5,6,11,8,9])来说的。
11,8,9          current_val=11 索引:low=4,high=6 初始值
9,8,11          current_val=11 索引:low=4,high=5 从后向前,交换
8,9,11          current_val=11 索引:low=5,high=5 从前向后,交换

第三次排序好的列表,就是最终结果,因为左边列表 和右边的列表,都分别得到了一个值。
最终结果:
[2,3,5,6,8,9,11]
‘‘‘

def quick_sort(aList, left,right):  # left 和right是为了递归用的。
    # if low==high and low>0:
    if left>=right:
        return
    low=left            # 这两句是为了递归用的
    high= right
    k = aList[left]     # 定的固定值,以它为标杆排序
    while low<high:
        # print ‘aList[low]:‘,aList[low]
        # print ‘aList[high]:‘,aList[high]
        # print ‘low:‘,low
        # print ‘high:‘,high
        print aList

# while high>0 low!=high and aList[low]<=aList[high]: # 此时 aList[low]是关键字,递归low的值。这是对的
        ‘‘‘
        注意:这里high是递减的,可能high会减成负数,会报错,所以high>0
        high是递减的,如果high减的跟low相等了,不应该再执行,结果再执行high-=1,则high<low,结果错误的交换了!

如下所示:
        [9, 12, 51, 17, 40, 68, 79, 83, 94, 83]
        low1: 5
        high1: 5
        low2: 5
        high2: 4
        [9, 12, 51, 17, 68, 40, 79, 83, 94, 83]

所以,这里应该写成:
        while high>0 and low!=high and aList[low]<=aList[high]:
        或者直接写成:
        while low<high and aList[low]<=aList[high]:
        ‘‘‘
        # 有时候有多个相同的元素,所以要写成<=
        while high>0 and low!=high and aList[low]<=aList[high]:
        # while high>0 and aList[low]<=aList[high]: # 此时 aList[low]是关键字,递归low的值。应该加上条件:and low!=high

# while high>0 and k<=aList[high]:    # 这样写也是对的,关键字就是k。这时候k就是aList[low]
            ‘‘‘
            if low==high:
                print ‘low1:‘,low
                print ‘high1:‘,high
            ‘‘‘
            high-=1
        print ‘low2:‘,low
        print ‘high2:‘,high
        temp=aList[low]         # 其实是low和high之间互换位置。
        aList[low]= aList[high]
        aList[high]=temp
        print aList
        #print ‘sec_aList[low]:‘,aList[low]
        #print ‘sec_aList[high]:‘,aList[high]
        # 因为low和high是互相变动的,有的时候low是关键字,有的时候high是关键字,有的时候low=high=关键字
        # 而每次while循环,都只针对一个固定值,小的放左边,大的放右边

‘‘‘
        这里也一样,如果low+=1的话,low和high相等的时候(本来不应该执行了),low再加1,则又做了错误的交换了。
        ‘‘‘
        while low!=high and aList[high]>aList[low]:   # 此时 aList[high]是关键字,递归low的值 是对的

#while aList[high]>aList[low]:   # 此时 aList[high]是关键字,递归low的值 ,应该加上条件:andand low!=high
        # while k>aList[low]: # 这样写也是对的,关键字就是k。这时候k就是aList[high]
            ‘‘‘
            if low==high:
                print ‘low3:‘,low
                print ‘high3:‘,high
            ‘‘‘
            low+=1
        temp=aList[high]
        aList[high]= aList[low]
        aList[low]=temp

#print ‘result:‘,aList
    # if low==high and low>0:
    # quick_sort(aList, 0,low-1)
    #print ‘left:‘,left
    #print ‘low-1:‘,low-1
    # quick_sort(aList, 0,low-1)
    quick_sort(aList, left,low-1)
    # quick_sort(aList, low+1,len(aList)-1)
    quick_sort(aList, low+1,right)

#print aList

‘‘‘
aList=[]
for i in range(20):
    aList.append(random.randrange(100))
print aList

aList=[6,2,5,11,3,8,9]

aList=[]
for i in range(10):
    aList.append(random.randrange(100))
‘‘‘

aList=[83, 83, 94, 51, 9, 79, 40, 68, 12, 17]
# aList=[83, 83, 94, 51, 9, 79, 40]
print aList
quick_sort(aList, 0,len(aList)-1)
print aList

时间: 2024-10-08 18:41:45

s11d27 算法的相关文章

经典排序算法 - 冒泡排序Bubble sort

 原文出自于 http://www.cnblogs.com/kkun/archive/2011/11/23/bubble_sort.html 经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 | 第一趟排序(外循环) 第

转载:DenseNet算法详解

原文连接:http://blog.csdn.net/u014380165/article/details/75142664 参考连接:http://blog.csdn.net/u012938704/article/details/53468483 本文这里仅当学习笔记使用,具体细节建议前往原文细度. 论文:Densely Connected Convolutional Networks 论文链接:https://arxiv.org/pdf/1608.06993.pdf 代码的github链接:h

基于位置信息的聚类算法介绍及模型选择

百度百科 聚类:将物理或抽象对象的集合分成由类似的对象组成的多个类的过程被称为聚类.由聚类所生成的簇是一组数据对象的集合,这些对象与同一个簇中的对象彼此相似,与其他簇中的对象相异."物以类聚,人以群分",在自然科学和社会科学中,存在着大量的分类问题.聚类分析又称群分析,它是研究(样品或指标)分类问题的一种统计分析方法.聚类分析起源于分类学,但是聚类不等于分类.聚类与分类的不同在于,聚类所要求划分的类是未知的. 分类和聚类算法一直以来都是数据挖掘,机器学习领域的热门课题,因此产生了众多的

密码算法详解——AES

0 AES简介 美国国家标准技术研究所在2001年发布了高级加密标准(AES).AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准. 根据使用的密码长度,AES最常见的有3种方案,用以适应不同的场景要求,分别是AES-128.AES-192和AES-256.本文主要对AES-128进行介绍,另外两种的思路基本一样,只是轮数会适当增加. 1 算法流程 AES加解密的流程图如下: AES加密过程涉及到4种操作:字节替代(SubBytes).行移位(ShiftRows).列混淆(MixCo

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

关于SVM数学细节逻辑的个人理解(三) :SMO算法理解

第三部分:SMO算法的个人理解 接下来的这部分我觉得是最难理解的?而且计算也是最难得,就是SMO算法. SMO算法就是帮助我们求解: s.t.   这个优化问题的. 虽然这个优化问题只剩下了α这一个变量,但是别忘了α是一个向量,有m个αi等着我们去优化,所以还是很麻烦,所以大神提出了SMO算法来解决这个优化问题. 关于SMO最好的资料还是论文<Sequential Minimal Optimization A Fast Algorithm for Training Support Vector

基于Spark MLlib平台的协同过滤算法---电影推荐系统

基于Spark MLlib平台的协同过滤算法---电影推荐系统 又好一阵子没有写文章了,阿弥陀佛...最近项目中要做理财推荐,所以,回过头来回顾一下协同过滤算法在推荐系统中的应用. 说到推荐系统,大家可能立马会想到协同过滤算法.本文基于Spark MLlib平台实现一个向用户推荐电影的简单应用.其中,主要包括三部分内容: 协同过滤算法概述 基于模型的协同过滤应用---电影推荐 实时推荐架构分析     一.协同过滤算法概述 本人对算法的研究,目前还不是很深入,这里简单的介绍下其工作原理. 通常,

算法 希尔排序

希尔排序 Shell Sort 介绍: 希尔排序(Shell Sort)也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率比直接插入排序有较大提高. 执行流程: 首先

算法 排序NB二人组 堆排序 归并排序

参考博客:基于python的七种经典排序算法     常用排序算法总结(一) 序前传 - 树与二叉树 树是一种很常见的非线性的数据结构,称为树形结构,简称树.所谓数据结构就是一组数据的集合连同它们的储存关系和对它们的操作方法.树形结构就像自然界的一颗树的构造一样,有一个根和若干个树枝和树叶.根或主干是第一层的,从主干长出的分枝是第二层的,一层一层直到最后,末端的没有分支的结点叫做叶子,所以树形结构是一个层次结构.在<数据结构>中,则用人类的血统关系来命名,一个结点的分枝叫做该结点的"