python实现常见八种内排序算法

版权声明:本文为博主原创文章,未经博主允许请尽情转载。 https://blog.csdn.net/yanghuan313/article/details/56090424
#!/usr/bin/python
# -*- coding: UTF-8 -*-

# python 实现八大内排序算法, 利用list对象的方法改变了部分过程

input_list = [3, 5, 9, 8, 7, 7, 6, 2, 4, 5]


# 直接插入排序
def insert_sort(alist):
    for x in xrange(len(alist)):
        for y in xrange(x):
            if alist[x] < alist[y]:
                # 原本对于有序区大于它的元素需要逐个后移,我使用insert和del方法简化操作
                alist.insert(y, alist[x])
                del alist[x+1]
    return alist


# 希尔排序 d = n/2 , d2 = d1/2 , 调用前面的直接插入排序算法
def shell_sort(alist):

    # 将直接插入的结果映射回原列表
    def map_result(blist, result_iter, index_list):
        for a in index_list:
            blist[a] = result_iter.next()
        return blist

    n = len(alist)
    gap = n/2
    while gap > 0:
        for x in xrange(gap):
            result_list = insert_sort(map(lambda a: alist[a], range(x, n, gap)))
            alist = map_result(alist, result_list.__iter__(), range(x, n, gap))
        gap /= 2
    return alist


# 冒泡排序
def bubble_sort(alist):
    n = len(alist)
    for x in xrange(n):
        for y in range(x + 1, n)[::-1]:
            if alist[y] < alist[y-1]:
                alist[y], alist[y-1] = alist[y-1], alist[y]
    return alist


# 快速排序
def quick_sort(alist, i, j):
    start, end = i, j
    if start < end:
        base = alist[start]
        while start != end:
            while end > start and alist[end] >= base:
                end -= 1
            alist[start] = alist[end]
            while end > start and alist[start] <= base:
                start += 1
            alist[end] = alist[start]
        alist[start] = base
        quick_sort(alist, i, start - 1)
        quick_sort(alist, start + 1, j)
    return alist


# 选择排序
def select_sort(alist):
    count = 0
    n = len(alist)
    while count < n:
        index = alist[count:].index(min(alist[count:])) + count
        alist[count], alist[index] = alist[index], alist[count]
        count += 1
    return alist


# 堆排序, 小根堆
# 调整堆的算法
def sift(alist, low, high):
    i, j = low, 2 * low
    root = alist[i]
    while j <= high:
        if j < high and alist[j] > alist[j+1]:
            j += 1
        if root > alist[j]:
            alist[i], i, j = alist[j], j, 2 * j
        else:
            break
    alist[i] = root


# 堆排序的算法
def heap_sort(alist):
    n = len(alist)
    result = []
    # 在0的位置插入一个元素,让下标从1开始
    alist.insert(0, -1)
    for x in range(1, n / 2 + 1)[::-1]:
        sift(alist, x, n)
    for y in range(2, n + 1)[::-1]:
        result.append(alist[1])
        alist[1], alist[y] = alist[y], alist[1]
        sift(alist, 1, y - 1)
    result.append(alist[1])
    return result


# 归并排序 这个算法参考自http://python.jobbole.com/82270/
def merge(left, right):
    i, j = 0, 0
    result = []
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result += left[i:]
    result += right[j:]
    return result


def merge_sort(alist):
    if len(alist) < 2:
        return alist
    num = len(alist) / 2
    left = merge_sort(alist[:num])
    right = merge_sort(alist[num:])
    return merge(left, right)


# 基数排序,不想写了

# merge_sort(input_list[:])
# heap_sort(input_list[:])
# select_sort(input_list[:])
# quick_sort(input_list[:], 0, len(input_list[:])-1)
# bubble_sort(input_list[:])
# print shell_sort(input_list[:])
# insert_sort(input_list[:])

网上大部分都有,但有一些地方我按照python特点做了些变化。

其中有一个让我很疑惑的地方,希尔排序的定义是:把记录按下标的一定增量分组,对每组使用直接插入排序算法排序。

我看过很多的博客,甚至包括我本科的数据结构教材,一概都是在算法中先分组,然后两两交换,但按照希尔排序的定义, 难道不是应该先分组,然后使用直接插入排序?, 网上和教材中使用的代码普遍是“希尔冒泡法”, 我不知道是我理解问题,还是大家的以讹传讹。

我贴出教材中的代码,有兴趣的朋友可以对照我上面的代码,看看有什么不同,

void ShellSort(int R[], int n)
{
    int i,j,gap;
    int tmp;
    gap = n / 2;
    while(gap > 0)
    {
        for(i = gap;i < n;i++)
        {
            tmp = R[i];
            j = j - gap;
            while(j >= 0 && tmp < R[j])
            {
                R[j + gap] = R[j];
                j = j - gap;
            }
            R[j + gap] = tmp;
        }
        gap = gap / 2;
    }
}

猜你喜欢

转载自blog.csdn.net/yanghuan313/article/details/56090424