对大量有重复数字的数组进行排序

题目:#给定一个数组,已知数组中有大量的重复数字,如何对数字进行高效的排序

 

思路一:Hash法

#coding=utf-8
#对大量有重复数字的数组进行排序
#给定一个数组,已知数组中有大量的重复数字,如何对数字进行高效的排序
arr = [16,13,16,3,3,13,3,4,13,101,4,4]
def sort_hash(a):
    """
        Hash法
        思路:创建一个hash表,然后遍历数组,若遍历的数在hash表中,对应的值+1
        若不存在,把遍历的值加入hash表中,并初始化key对应的值为1
        对hash 的key 进行快速排序(Mlog2M, M 为数组中不同数字的个数) 
        时间复杂度: N + Mlog2M
        空间复杂度:N
    """
    b = dict()
    for i in range(len(a)):
        if a[i] in b:
            b[a[i]] +=1
        else:
            b[a[i]] = 1
    c = b.keys()
    sort_quick(c, 0, len(b.keys())-1)
    print c
    for i in c:
        while(b[i]>0):
            print i
            b[i]-=1

def sort_quick(lists, low, high):
    if low >= high:
        return lists
    i,j = low, high
    key = lists[low]
    while(low < high):
        while(low=lists[low]):
            low += 1
        lists[high] = lists[low]
        lists[low] = key
    sort_quick(lists, i, low-1)
    sort_quick(lists, low+1, j)
def test_quick():
    lists = [49, 38, 65, 97, 76, 13, 27, 49]
    print 'before sort: ', lists
    sort_quick(lists, 0, len(lists)-1)
    print 'after sort: ', lists
test_quick()
sort_hash(arr)

思路二:AVL树(使用常规的排序方法,最好的排序算法时间复杂度为Nlog2N,未使用到题中条件存在大量重复的数)

"""
思路:根据数组中的树构建一个AVL树(对该AVL树做适当的调整,在节点中增加一个额外的数据域来记录这个数字出现的次数
       在AVL构建完成后,对AVL树进行中序遍历,根据每个节点对应数字出现的次数,把遍历结果放入数组中完成排序)
"""
class Node:
    def __init__(self, data):
        self.data = data
        self.left = self.right = None
        self.height = 1
        self.count = 1

class Sort:
    def order(self,arr,root,index):
        if root != None:
            index = self.order(arr,root.left,index)
            for i in range(root.count):
                arr[index] = root.data
                index += 1
            index = self.order(arr,root.right,index)
        return index

    def get_height(self,node):
        if node == None:
            return 0
        else:
            return node.height

    def Rotate_right(self, T):
        #左左型: 单旋转右旋
        L = T.left
        T.left = L.right
        L.right = T
        T.height = max(self.get_height(T.left), self.get_height(T.right)) + 1
        L.height = max(self.get_height(L.left), self.get_height(L.right)) + 1
        return L

    def Rotate_left(self, T):
        #右右型: 单旋转左旋
        R = T.right
        T.right = R.left
        R.left = T
        T.height = max(self.get_height(T.left), self.get_height(T.right)) + 1
        L.height = max(self.get_height(L.left), self.get_height(L.right)) + 1

     def Rotate_left_right(self, T):
        #双旋转,先左后右
        T.left = Rotate_left(self, T.left)
        return Rotate_right(T)

    def Rotate_right_left(self, T):
        T.right = Rotate_right(self, T.right)
        return Rotate_left(T)


    def insert(self, T, data):
        if T == None:
            return Node(data)
        if data == T.data:
            T.count += 1
            return T
        elif data < T.data:
            T.left = self.insert(T.left, data)
        else:
            T.right = self.insert(T.right, data)

        T.hegiht = max(self.get_height(T.left), self.get_height(T.right)) + 1
        balance = self.get_height(T.left) - self.get_height(T.right)

        if balance > 1 and data < T.left.data:
            return self.Rotate_right(T) #LL
        elif  balance < -1 and data > root.right.data:
            return Rotate_left(T) #RR
        elif balance > 1 and data > T.left.data:
            return Rotate_left_right(T) #LR
        elif balance < -1 and data < root.right.data:
            return Rotate_right_left(T) #RL
        return T


    def sort(self, arr):
        root = None
        for i in range(len(arr)):
            root = self.insert(root, arr[i])
        index = 0
        self.order(arr, root, index)
s = Sort()
s.sort(arr)
for i in arr:
    print i

 

你可能感兴趣的:(算法+数据结构)