算法與數據結構

算法與數據結構

算法

一、排序算法mysql

  1. 冒泡排序
  2. 選擇排序
  3. 插入排序
  4. 快速排序
  5. 希爾排序
  6. 計數排序

二、列表查找算法

從列表中查找指定的元素sql

  1. 順序查找

    從列表第一個元素開始,順序進行搜索,直到找到爲止數組

  1. 二分查找

    從有序列表的候選區data[0: n]開始,經過對待查找的值與候選區中的值比較使候選區的值減半數據結構

數據結構與算法動態可視化app

1. 算法的衡量標準

  1. 時間複雜度

時間複雜度:程序執行的大概次數,使用O()來計函數

 logn == log2^n優化

 如何一眼判斷時間複雜度:ui

  1. 循環減半的過程 ==》O(logn)spa

  2. 幾回循環就是n的幾回方的複雜度

  2. 空間複雜度

用來評估算法內存佔用大小的一個式子

2. 冒泡排序

首先列表每相鄰兩個數進行比較,若是前面的比後面的大,就交換兩個數

# 冒泡排序 # 時間複雜度:O(n^2)
def bubble_sort(li):
    for i in range(len(li) - 1):  # 趟數
        flag = True
        for j in range(len(li) - 1 - i):  # 每一趟內層循環,每一趟肯定一個比較次數-i
            if li[j] > li[j + 1]:  # 前面大於後面交換位置
                li[j], li[j + 1] = li[j + 1], li[j]
                flag = False
        if flag:  # 優化:若是一趟循環下來都沒有要比較交換的位置說明本來就是順序的,直接返回
            return

3. 選擇排序

先選擇一個數,默認該數是最小的放在第一的位置,而後再一次遍歷取出全部的數與第一個數比較,若是比他大交換位置

# 選擇排序 # 時間複雜度:O(n^2)
def select_sort(li):
    for i in range(len(li)):
        # 將取出的第一個默認是最小的
        minloc = i
        for j in range(i + 1, len(li)):
            # 循環比較後面的全部值與 第一個元素比較
            if li[minloc] > li[j]:
                # 若是比第一個元素小就換位置
                li[minloc], li[j] = li[j], li[minloc]

4. 插入排序

列表被分爲有序區域無序區兩個部分,最初有序區就一個元素,每次從無序區取出一個元素,插入到有序區的位置,直到無序區變空

# 插入排序 # 時間複雜度:O(n^2)
def insert_sort(li):
    # 將第一個元素做爲有序區第一個元素
    for i in range(1, len(li)):
        # 將無序區中的元素取出拿一個變量存着
        tmp = li[i]
        # 獲取取去的前一個元素的索引
        j = i - 1
        # 比較取出的元素與前面的全部元素
        while j >= 0 and li[j] > tmp:
            # 前面的值覆蓋取出的值
            li[j + 1] = li[j]
            # 依次循環前面的全部值
            j = j - 1
        # 比較完j=-1跳出循環,將取出的值做爲第一個
        li[j + 1] = tmp

5. 快速排序

取一個元素p(第一個元素),使p其歸位,列表被p分爲兩部分,左邊的都比p小,右邊的比p大,最後遞歸完成排序

# 快速排序 # 時間複雜度:O(nlogn)
def quick_sort(li, left, right):
    # left與right是左右兩邊的索引
    if left < right:
        # 調用歸爲函數獲得中間的索引
        mid = partition(li, left, right)
        # 遞歸減半左右兩邊
        quick_sort(li, left, mid-1)
        quick_sort(li, mid+1, right)


# 歸爲函數
def partition(li, left, right):
    # 將第一個元素取出
    tem = li[left]
    while left < right:
        # 判斷右邊的是否比取出的第一個元素大,若是大指針移動一位
        while left < right and li[right] >= tem:
            right = right - 1
        # 若是右邊的比第一個小,將該元素賦值給左邊
        li[left] = li[right]
        
        # 判斷左邊的元素是否比取出的元素小,若是小指針移動一位
        while left < right and li[left] <= tem:
            left = left + 1
        # 若是左邊的比取出的大,將該元素賦值給剛右邊元素的位置
        li[right] = li[left]
    # 當指針重合時,將取出的第一個元素放下在中間
    li[left] = tem
    mid = left  # 或者等於right,兩邊指針重合時
    return mid

# quick_sort(li, 0, len(li)-1)

6. 希爾排序

一、希爾排序是一種分組插入排序的算法

二、首先取一個整數d1 = n/2,將元素分爲d1個組,每組相鄰元素之間距離爲d1,在各組內進行直接插入排序

三、再取第二個整數重複上述分組過程,直到di = 1,全部元素在用一個組內進行直接插入排序

四、希爾排序每一趟只是讓元素接近有序,最後一趟使全部元素有序

時間複雜度:O(1.3n)

7. 計數排序

時間複雜度:O(n)

def count_sort(li):
    # 先生成比列表多一個的列表全是0
    count = [0 for i in range(len(li)+1)]
    # 將列表循環取出對應的count=1
    print(count)
    for i in li:
        count[i] += 1
    print(count)
    # 將原列表清空後再添加
    li.clear()
    # 枚舉出count
    for k, v in enumerate(count):
        print(k, v)
        # 去除0和保證重複的數在裏面
        for i in range(v):
            li.append(k)

8. 二分查找

時間複雜度:O(logn)

def bin_search(li, value, low, high):
    if low <= high:
        mid = (low + high) // 2
        if li[mid] == value:
            return mid
        elif li[mid] > value:
            return bin_search(li, value, low, mid-1)
        else:
            return bin_search(li, value, mid+1, high)
    else:
        return

數據結構

一、線性結構

就是可以用一根線串起來的數據結構

  1. 數組(列表)

一、申請數組的前提條件是:內存是連續

二、int a[7] :表明聲明一個數組是a,數組大小是7,數組的元素都是整型

一個數長度是4個字節因此7個是28個字節

三、如何申請內存:在C, C++ 語言中,mallco(28)申請28個字節,用完後要釋放: free(28)

四、若是 int a[7] = [1, 2, 3, 4, 5, 6, 7]  那如何知道 a[3] = 4的?

a[3] = 首地址(1000) + 索引(3) * 長度(4)= 1012--1015

五、首地址是保存在數組名中的

  1. 鏈表(約瑟夫問題、丟手絹問題)

數組要一塊連續的內存空間來存儲,對內存的要求比較高。若是咱們申請一個 100MB 大小的數組,當內存中沒有連續的、足夠大的存儲空間時,即使內存的剩餘總可用空間大於 100MB,仍然會申請失敗。 而鏈表偏偏相反,它並不須要一塊連續的內存空間,它經過「指針」將一組零散的內存塊串聯起來使用,因此若是咱們申請的是 100MB 大小的鏈表,根本不會有問題。

 3. 鏈表分類:

  • 單鏈表
  • 雙鏈表,每個節點有兩個指針域
  • 循環鏈表 ,能經過任何一個節點找到其餘全部的節點
  • 非循環鏈表
  •  每個節點有兩個指針域
  • 循環鏈表 能經過任何一個節點找到其餘全部的節點
  • 非循環鏈表
  1. 線性結構的應用  
    • 隊列

二、非線性結構

    • 通常樹:任意一個節點的子節點的個數不受限制
      • B+樹
    • 二叉樹:任意一個節點的子節點的個數最可能是兩個,且子節點的位置不可更改
      • 徹底二叉樹:只是刪除了滿二叉樹最底層最右邊連續的若干個節點
      • 滿二叉樹:在不增長層數的前提下,沒法再多添加一個節點的二叉樹
    • 森林:n個互不相交的數的集合
    • mysql的索引:B+樹

 

相關文章
相關標籤/搜索