線性表排序算法

一、排序算法的穩定性node

指通過特定規則進行排序後,兩個都知足排序規則,沒法判斷,哪個排在前面,哪個排在後面,這類的元素,若是按照原來的順序,進行排列,則爲穩定,不然爲不穩定。python

舉例, (4,1),(3,1),(3,7),(5,6),咱們將這個四個元祖,以第一個元素的大小,從小到大進行排序。那麼對於(3,1)和(3,7)而言有兩種排列方式算法

(3,1),(3,7),(4,1),(5,6)這種排序中的(3,1),(3,7)是以原來的順序進行排列的,稱之爲穩定。shell

(3,7),(3,1),(4,1),(5,6)這種改變了原來的排序方式,稱之爲不穩定。數組

 

 

二、排序算法們數據結構

2.1 冒泡排序app

冒泡排序的基本思想:函數

                               每個元素都和下一個元素進行比較大小,哪個元素大就將大的元素向後移動,而後這個大的元素,在和下一個元素進行比較,一次向下進行,直到隊列的尾部,這樣就找了最大數。post

                               而後開始第二次進行進行上面的步驟,找到第二大的數。依次向下進行。ui

 

def bubblesort(sequence):
    length = len(sequence) #獲取序列的長度
    for i in range(length-1):  #一共要循環這個序列多少次
        #考慮特殊狀況 ,就是這個序列自己就是一個有序的,那麼對於這個序列來說,我就沒有
        #進行過位置互換,因此,當進入循環進行判斷後,這個count一遍是一直沒有執行的,#
        #若是第一次所有比較事後,都沒有發生過替換,直接退出便可
        count = 0
        for j in range(length-1-i):  #每一次循環,循環序列中元素的個數
            if  sequence[j]>sequence[j+1]:  #當前元素和後一個元素進行大小判斷
                sequence[j], sequence[j+1] = sequence[j+1], sequence[j]  #進行位置互換
                count += 1
        if count == 0:
            return sequence
    return sequence

if __name__ == '__main__':
    a = [10,30,15,12,6,9,45,2,6,50]
    print(a)
    print(bubblesort(a))

  

2.2 選擇排序

 

def selectsort(sequence):
    '''選擇排序'''

    n = len(sequence)  #獲取列表的長度

    for i in range(n-1):  #判斷這種邏輯須要多少次
        min=i
        for j in range(1+i , n-1): #每一次循環,都是取current爲最小值,和後面進行判斷,找到最小值後,將最小值與當前值位置互換。
            if sequence[min] >sequence[j]:
                min = j
        sequence[i], sequence[min] = sequence[min], sequence[i]
    return sequence

print(selectsort([1,10,50,22,12,44,66]))

  

2.3插入排序

#插入排序與選擇排序相似,都輸將一個序列分爲兩個部分,針對插入排序,將前面做爲有序部分,將一個元素,做爲有序部分的第一個元素,而後從
#第二個元素開始和前面有序中的每個元素進行循環對比,若是比有序部分的元素小,就交換位置。

def insert_sort(sequence):

    n = len(sequence)
    for i in range(1, n):

        while i>0:
            if sequence[i] < sequence[i-1]:
                sequence[i-1], sequence[i] = sequence[i], sequence[i-1]
                i -=1
            else:
                break

    return sequence


print(insert_sort([1,10,50,22,12,44,66]))

  

2.4希爾排序

 

#首先說一下希爾排序的一個思想,希爾排序是一個間隙gap和插入排序的組成。
#首先說他的gap ,他根據gap,將一個序列分紅若干個部分
#例如 一個隊列[1,10,8,9,33,15,99],加入說gap是3 ,那麼分紅的[1,10,8],
#[9,33,15], 和[9]這三部分進行對比 ,
# [1,10,8]
# [9,33,15]
# [99]
# 他們進行豎向對比,就是豎向對比的規則就是插入排序。
# 當一次對比完成後,將gap縮小,直到是1,當gap是1的,就徹底就是插入排序了。有點雞肋這個希爾排序


def shell_sort(sequence):

    n = len(sequence)

    gap = n//2   #獲取間隙大小

    while gap >= 1:
        for i in range(gap, n):  #循環多少次 ,這個次數的判斷,就看上面咱們豎向對比的時候,有一箇中間位置, [1]      [9]   [99]
            j =i                 #                                                                [10]    [33]
            while j>0:           #                                                                   [8]     [15]
                if sequence[j] < sequence[j-gap]:#那麼對咱們來講就是從9和你開始作對比,9是第一次,99是最後一次,99對應的下標是n-1,9對應的下標是gap,因此兩者相減就是次數
                    sequence[j-gap], sequence[j] = sequence[j], sequence[j-gap]
                j -= gap
        gap = gap//2

    return sequence


print(shell_sort([1,10,50,22,12,44,66]))

  

2.5

快速排序,使用遞歸實現快排

#使用遞歸,重要的思想有三點,
一、遞歸必需要有一個基線條件(就是終止遞歸的條件),通常像線性表這種數據結構,
遞歸條件就表中的元素爲1或者爲空。

二、就是排序算法自己,先取列表中一個元素爲中間元素,循環整個列表,將大於當前元素,放入一個新的列表,而後在將小於這個元素放入一個列表。而後將列表中不斷按照這種原則進行一個分拆,最後,在將這些列表相加在一塊兒。

三、關於爲何,遞歸可以獲取以前函數的值,由於遞歸會產生調用棧,每一次遞歸都會在棧中保存,上一次函數調用的變量的值。

def quick_sort(sequence):

    if len(sequence)==0:
        return sequence

    else:
        middle = sequence[0]
        min = [i for i in sequence[1::] if i < middle]
        max = [i for i in sequence[1::] if i > middle]
        return quick_sort(min) + [middle] + quick_sort(max)



print(quick_sort([33,10,50,22,12,44,66,55,999,24]))

  

 2.6 merge_sort

'''
歸併排序的思想是,將sequence,均分紅兩個部分,直接將每個部分,都分紅,只有一個元素位置
例如 [10,8,22,15] ,先分紅[10,8],[22,15]而後在將這個兩個數組在劃分,[10,8]劃分紅[10],[8]到達這種狀態。
分紅每個部分都只有一個元素後,就開始對比合並 ,首先咱們看[10],[8],兩個對比,[8],將先8放入到一個空數組中
而後在和[10]merge ,筒體[22,15】重複上述操做,合併成了[15,22] ,這時候[8,10]和[15,22]在開始合併,
先將每個數組中的第一個元素進行對比,小的先放到一個數組中,而後在拿這個數和[10]比較,若是仍是10小,就將10也
放到這個列表中,而後在將[8,10]和[15,22]合併,最後就是一個有序的序列了


'''

def mergesort(sequence):
    '''歸併排序'''
    if len(sequence)==1:
        return sequence

    n = len(sequence)
    middle = n // 2
    left_li = mergesort(sequence[:middle])
    right_li = mergesort(sequence[middle:])

    res = []
    left_cursor, right_cursor=0, 0
    while left_cursor<len(left_li) and right_cursor<len(right_li):
        if left_li[left_cursor]<right_li[right_cursor]:
            res.append(left_li[left_cursor])
            left_cursor += 1

        else:
            res.append(right_li[right_cursor])
            right_cursor += 1

    res += left_li[left_cursor:]
    res += right_li[right_cursor:]

    return res


print(mergesort([1,10,50,22,12,44,66]))

  

 

2、 樹

 

 有序樹

      一、  二叉樹

                    1.1徹底二叉樹

                    1.2 

      二、霍夫曼樹

      三、B樹

 

下面全部的代碼都是基於二叉樹實現,都是爲了實現一個滿二叉樹

 

二、1 二叉樹添加節點及,廣度serversal

class Node(object):
    '''樹節點'''
    def __init__(self, ele):
        self._ele = ele
        self.left_node = None
        self.right_node = None

class Tree(object):
    def __init__(self):
        self.__root = None

    def add(self, item):
        '''添加節點,經過層級遍歷,實現二叉樹'''

        node = Node(item)
        if self.__root is None:
            self.__root = node
            return
        queue = [self.__root]  #先將跟節點放入隊列中
        while queue:
            cur_node = queue.pop(0)
            if cur_node.left_node is None:
                cur_node.left_node = node
                return
            else:
                queue.append(cur_node.left_node)

            if cur_node.right_node is None:
                cur_node.right_node = node
                return
            else:
                queue.append(cur_node.right_node)


    def leveltraversal(self):

        queue = []
        queue = [self.__root]  # 先將跟節點放入隊列中
        while queue:
            cur_node = queue.pop(0)
            print(cur_node._ele)

            if cur_node.left_node is None:
                pass
            else:
                queue.append(cur_node.left_node)

            if cur_node.right_node is None:
                pass
            else:
                queue.append(cur_node.right_node)



if __name__ == '__main__':

    tree = Tree()

    for i in range(10):
        tree.add(i)


    tree.leveltraversal()

  

二叉樹縱向遍歷,分爲三中分別是前序、中序、後序。這三種遍歷的區別在遍歷順序前序是根節點 - 左邊的節點 - 右邊的節點 , 中序是 左邊的節點 - 根節點 - 右邊的節點 , 後序是作節點 - 右節點 - 根節點。(這個根節點若是是子樹,對應的就是父節點)

這個要注意的是在縱向遍歷時,若是向下遍歷的節點,不是葉節點,也就是對應的仍然是一個子樹,那麼就要按照遍歷規則,繼續向下遍歷。這些遍歷利用了遞歸的思想。

class Node(object):
    '''樹節點'''
    def __init__(self, ele):
        self._ele = ele
        self.left_node = None
        self.right_node = None

class Tree(object):
    def __init__(self):
        self.root = None

    def add(self, item):
        '''添加節點,經過層級遍歷,實現二叉樹'''

        node = Node(item)
        if self.root is None:
            self.root = node
            return
        queue = [self.root]  #先將跟節點放入隊列中
        while queue:
            cur_node = queue.pop(0)
            if cur_node.left_node is None:
                cur_node.left_node = node
                return
            else:
                queue.append(cur_node.left_node)

            if cur_node.right_node is None:
                cur_node.right_node = node
                return
            else:
                queue.append(cur_node.right_node)


    def leveltraversal(self):

        queue = []
        queue = [self.root]  # 先將跟節點放入隊列中
        while queue:
            cur_node = queue.pop(0)
            print(cur_node._ele)

            if cur_node.left_node is None:
                pass
            else:
                queue.append(cur_node.left_node)

            if cur_node.right_node is None:
                pass
            else:
                queue.append(cur_node.right_node)

    def prevtraversal(self, node):
        '''先序'''
        if node is None:
             return
        print(node._ele, end='')
        print('')
        self.prevtraversal(node.left_node)

        self.prevtraversal(node.right_node)




    def infixtraversal(self, node):
        '''中序'''

        if node is None:
            return

        self.infixtraversal(node.left_node)
        print(node._ele, end='')
        print('')
        self.infixtraversal(node.right_node)


    def postordertraversal(self, node):
        '''後序'''

        if node is None:
            return
        self.postordertraversal(node.left_node)
        self.postordertraversal(node.right_node)
        print(node._ele, end='')
相關文章
相關標籤/搜索