各种常用排序算法python实现

各种排序算法,常见的都有了!

import queue

def print_result_after(f):
    def wrapper(*args):
        ret = f(*args)
        print(ret)
        return ret
    return wrapper


def binary_search(data,elem,almost = False,start=None,end=None):
    if start is None:
        start = 0

    if end is None:
        end = len(data)

    if end <= start:
        return None

    while start < end:

        mid = (start + end)//2

        if data[mid] == elem:
            return mid
        elif data[mid] < elem:
            start = mid + 1
        else:
            end = mid

    if almost:
        return start
    else:
        return None


@print_result_after
# 第一个数字无效,用来当哨兵
def insert_sort(data):
    for i in range(2,len(data),1):
        data[0] = data[i]

        j = i - 1
        while data[0] < data[j]:
            data[j+1] = data[j]
            j -= 1
        data[j+1]= data[0]

    data[0] = None
    return data


@print_result_after
def insert_sort_using_binary_search(data):
    for i in range(1,len(data),1):
        elem = data[i]
        proper_index = binary_search(data,elem,True,1,i)

        j = i-1
        while j >= proper_index:
            data[j+1] = data[j]
            j -= 1
        data[proper_index] = elem

    return data


@print_result_after
def bubble_sort(data):
    for i in range(len(data)):
        j = len(data) - 1
        has_swap = False

        while j > i:
            if data[j] < data[j-1]:
                data[j],data[j-1] = data[j-1],data[j]
                has_swap = True

            j -= 1

        if not has_swap:
            return data

    return data


# 递归实现
def quick_sort(data,start,end):
    if start >= end:
        return

    index = partition(data,start,end)
    quick_sort(data,start,index)
    quick_sort(data,index + 1,end)


# 使用栈实现
def quick_sort_using_stack(data):
    if data is None or len(data) == 0:
        return

    stack = queue.LifoQueue()
    stack.put([0,len(data)])
    while not stack.empty():
        start,end = stack.get()
        index = partition(data,start,end)
        if start < index:
            stack.put([start,index])
        if (index + 1) < end:
            stack.put([index + 1,end])


# 使用队列实现
# 见文章《用栈和队列实现快速排序算法》http://www.jianshu.com/p/cadc9e830d09
def quick_sort_using_queue(data):
    if data is None or len(data) == 0:
        return

    stack = queue.Queue()
    stack.put([0,len(data)])
    while not stack.empty():
        start,end = stack.get()
        index = partition(data,start,end)
        if start < index:
            stack.put([start,index])
        if (index + 1) < end:
            stack.put([index + 1,end])


def partition(data,start,end):
    # 只有一个元素
    if start == end - 1:
        return start

    pivot = data[start]
    last = end - 1

    while True:
        # 相等的时候是只剩下一个,那个位置是主元的
        while start < last:
            if data[last] < pivot:
                data[start] = data[last]
                start += 1
                break
            else:
                last -= 1
        else:
            data[start] = pivot
            return start

        while start < last:
            if data[start] > pivot:
                data[last] = data[start]
                last -= 1
                break
            else:
                start += 1
        else:
            data[start] = pivot
            return start


def is_even(elem):
    return elem % 2 == 0


def partition_odd_even(data):
    start = 0
    last = len(data) - 1

    while start <= last:
        if not is_even(data[start]):
            data[start],data[last] = data[last],data[start]
            last -= 1
        else:
            start += 1


# k:0~n-1
@print_result_after
def find_kth_elem(data,k):
    if k >= len(data) or k < 0:
        return None

    start = 0
    end = len(data)

    index = partition(data, start, end)
    while index != k:
        if k < index:
            end = index
            index = partition(data,start,end)
        else:
            start = index + 1
            index = partition(data, index + 1, index)
    return data[index]


@print_result_after
def selection_sort(data):
    # 最后一个自定
    for i in range(len(data)-1):
        pivot = i
        for j in range(i + 1,len(data)):
            if data[j] < data[pivot]:
                pivot = j

        if pivot != j:
            data[pivot],data[i] = data[i],data[pivot]

    return data


# 大堆
class max_heap(object):
    def __init__(self,data):
        self.data = data
        for i in range(len(data)//2 + 1,0,-1):
            self.max_heapify(i)

    def max_heapify(self,node_index,length=None):
        if node_index > len(self.data):
            return

        data = self.data
        if not length:
            length = len(data)

        lc_index = node_index*2
        rc_index = node_index*2+1

        max_index = node_index
        if lc_index < length and data[lc_index] > data[max_index]:
            max_index = lc_index

        if rc_index < length and data[rc_index] > data[max_index]:
            max_index = rc_index

        if max_index != node_index:
            data[node_index],data[max_index] = data[max_index],data[node_index]
            return self.max_heapify(max_index,length)

    @print_result_after
    def heap_sort(self):
        data = self.data
        for i in range(len(data)-1,0,-1):
            print(i)
            data[1],data[i] = data[i],data[1]
            self.max_heapify(1,i)
        return data

    def is_max_heap(self,root=1):
        lc_child = root*2
        if lc_child < len(self.data) and self.data[lc_child] > self.data[root]:
            return False

        rc_child = root * 2
        if rc_child < len(self.data) and self.data[rc_child] > self.data[root]:
            return False

        if lc_child < len(self.data):
            ret = self.is_max_heap(lc_child)
            if not ret:
                return False

        if rc_child < len(self.data):
            ret = self.is_max_heap(rc_child)
            if not ret:
                return False

        return True


def merge(data,start,mid,end):
    buff = data.copy()

    i = start
    j = mid
    step = start
    while i<mid and j<end:
        if buff[i] < buff[j]:
            data[step] = buff[i]
            i += 1
            step += 1
        else:
            data[step] = buff[j]
            j += 1
            step += 1

    while i < mid:
        data[step] = buff[i]
        i += 1
        step += 1

    while j < end:
        data[step] = buff[j]
        j += 1
        step += 1

    return data


def merge_sort(data,start,end):
    # 0、1、负数个返回
    if start >= end-1:
        return

    mid = (start + end)//2
    merge_sort(data,start,mid)
    merge_sort(data,mid,end)
    merge(data,start,mid,end)

    return data


def main():
    data = [2,4,1,0,6,7,5]
    merge_sort(data,0,len(data))
    print(data)


if __name__ == '__main__':
    main()

归并排序java版本

    public static void mergeSort(int[] nums) {
        doMergeSort(nums,0, nums.length);
    }

    private static void doMergeSort(int[] nums, int start, int end) {
        if((end-start)<=1){
            return ;
        }

        int mid = (start+end)/2;
        doMergeSort(nums, start, mid);
        doMergeSort(nums, mid, end);
        merge(nums, start, mid, end);
    }

    public static void merge(int[] nums, int start, int mid, int end) {
        int numMerge = end - start;
        int[] temp = new int[numMerge];

        int s1 = start;
        int e1 = mid;
        int s2 = mid;
        int e2 = end;
        int i = 0;
        while(s1<e1&&s2<e2){
            if(nums[s1]<nums[s2]){
                temp[i++] = nums[s1++];
            }else{
                temp[i++] = nums[s2++];
            }
        }

        while(s1<e1){
            temp[i++] = nums[s1++];
        }

        while(s2<e2){
            temp[i++] = nums[s2++];
        }

        i = 0;
        while(start<end){
            nums[start++] = temp[i++];
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容