面試準備9

淺談數據結構與算法:
數據結構與算法就是兵法-----------數據結構和算法是一名程序開發人員的必備基本功,需要平時不斷的積累學習

算法的概念:算法是獨立存在的一種解決問題的方法和思想,對於算法而言,實現語言並不重要,重要的是思想,算法可以有不同的語言描述實現版本。

算法的五大特性:
輸入:算法具有0個或多個輸入
輸出:算法至少有1個或多個輸出
有窮性:算法在有限的步驟之後會自動結束而不會無限循環
確定性:算法中的每一步都有確定的含義,不會出現二義性
可行性:算法的每一步都是可行的,也就是說每一步都能夠在有限的步驟結束

(1)算法效率衡量
執行時間反應算法效率:實現算法程序的執行時間可以反應出算法的效率,即算法的優劣。單純依靠運行的時間來比較算法的優劣並不一定是客觀準確的

(2)時間複雜度與大O表示法
對於算法進行特別具體的細緻分析雖然很好,但在實踐中的實際價值有限。對於算法的時間性質和空間性質,最重要的是其數量級和趨勢,這些是分析算法效率的主要部分。而計量算法基本操作數量的規模函數中那些常量因子可以忽略不計。例如,可以認爲3n2和100n2屬於同一個量級,如果兩個算法處理同樣規模實例的代價分別爲這兩個函數,就認爲它們的效率“差不多”,都爲n2級。

分析算法時,存在幾種可能的考慮:
算法完成工作最少需要多少基本操作,即最優時間複雜度
算法完成工作最多需要多少基本操作,即最壞時間複雜度
算法完成工作平均需要多少基本操作,即平均時間複雜度
我們主要關注算法的最壞情況,亦即最壞時間複雜度。

(3)時間複雜度的幾條基本計算規則

基本操作,即只有常數項,認爲其時間複雜度爲O(1)
順序結構,時間複雜度按加法進行計算
循環結構,時間複雜度按乘法進行計算
分支結構,時間複雜度取最大值
判斷一個算法的效率時,往往只需要關注操作數量的最高次項,其它次要項和常數項可以忽略

在沒有特殊說明時,我們所分析的算法的時間複雜度都是指最壞時間複雜度,一般考慮時間複雜度的情況比較多。

(4)常見時間複雜度
12 O(1) 常數階
2n+3 O(n) 線性階
3n2+2n+1 O(n2) 平方階
5log2n+20 O(logn) 對數階
2n+3nlog2n+19 O(nlogn) nlogn階
6n3+2n2+3n+4 O(n3) 立方階
2n O(2n) 指數階
在這裏插入圖片描述python內置的操作時間複雜度:
在這裏插入圖片描述
在這裏插入圖片描述(4)數據
數據是一個抽象的概念,將其進行分類後得到程序設計語言中的基本類型。如:int,float,char等。數據元素之間不是獨立的,存在特定的關係,這些關係便是結構。數據結構指數據對象中數據元素之間的關係。
Python給我們提供了很多現成的數據結構類型,這些系統自己定義好的,不需要我們自己去定義的數據結構叫做Python的內置數據結構,比如列表、元組、字典。而有些數據組織方式,Python系統裏面沒有直接定義,需要我們自己去定義實現這些數據的組織方式,這些數據組織方式稱之爲Python的擴展數據結構,比如棧,隊列等。

(5)算法和數據結構的區別
數據結構只是靜態的描述了元素之間的關係,高效的程序需要在數據結構的基礎上設計和選擇算法
程序=數據結構+算法
算法是爲了解決實際問題而設計的,數據結構是算法需要處理的問題載體

(6)抽象數據類型
抽象數據類型(ADT)的含義是指一個數學模型以及定義在此數學模型上的一組操作。即把數據類型和數據類型上的運算捆在一起,進行封裝。引入抽象數據類型的目的是把數據類型的表示和數據類型上運算的實現與這些數據類型和運算在程序中的引用隔開,使它們相互獨立。最常用的數據運算有五種:
插入、刪除、修改、修改、查找、排序

(7)順序表—線性表
根據線性表的實際存儲方式,分爲兩種實現模型:

順序表,將元素順序地存放在一塊連續的存儲區裏,元素間的順序關係由它們的存儲順序自然表示。

鏈表,將元素存放在通過鏈接構造起來的一系列存儲塊中。

(8)順序表的兩種實現形式
在這裏插入圖片描述(9)python中的順序表
python中的list和tuple兩種類型採用了順序表的實現技術,tuple是不可變類型,即不變的順序表,因此不支持改變其內部狀態的任何操作,而其他方面,則與list的性質類似。

list的基本實現技術:
Python標準類型list就是一種元素個數可變的線性表,可以加入和刪除元素,並在各種操作中維持已有元素的順序(即保序),而且還具有以下行爲特徵:

基於下標(位置)的高效元素訪問和更新,時間複雜度應該是O(1);

爲滿足該特徵,應該採用順序表技術,表中元素保存在一塊連續的存儲區中。

允許任意加入元素,而且在不斷加入元素的過程中,表對象的標識(函數id得到的值)不變。

爲滿足該特徵,就必須能更換元素存儲區,並且爲保證更換存儲區時list對象的標識id不變,只能採用分離式實現技術。

在Python的官方實現中,list就是一種採用分離式技術實現的動態順序表。這就是爲什麼用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。

在Python的官方實現中,list實現採用瞭如下的策略:在建立空表(或者很小的表)時,系統分配一塊能容納8個元素的存儲區;在執行插入操作(insert或append)時,如果元素存儲區滿就換一塊4倍大的存儲區。但如果此時的表已經很大(目前的閥值爲50000),則改變策略,採用加一倍的方法。引入這種改變策略的方式,是爲了避免出現過多空閒的存儲位置。

(10)鏈表
爲什麼需要使用鏈表:順序表的構建需要預先知道數據大小來申請連續的存儲空間,而在進行擴充時需要進行數據的搬遷,使用起來不靈活,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。
鏈表的定義

鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是不像順序表一樣連續存儲數據,而是在每一個節點(數據存儲單元)裏存放下一個節點的位置信息(即地址)。
在這裏插入圖片描述在這裏插入圖片描述
節點實現:

class SingleNode(object):
    """單鏈表的結點"""
    def __init__(self,item):
        # _item存放數據元素
        self.item = item
        # _next是下一個節點的標識
        self.next = None

單鏈表的操作:
is_empty() 鏈表是否爲空
length() 鏈表長度
travel() 遍歷整個鏈表
add(item) 鏈表頭部添加元素
append(item) 鏈表尾部添加元素
insert(pos, item) 指定位置添加元素
remove(item) 刪除節點
search(item) 查找節點是否存在

單鏈表的實現:

class SingleLinkList(object):
    """單鏈表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判斷鏈表是否爲空"""
        return self._head == None

    def length(self):
        """鏈表長度"""
        # cur初始時指向頭節點
        cur = self._head
        count = 0
        # 尾節點指向None,當未到達尾部時
        while cur != None:
            count += 1
            # 將cur後移一個節點
            cur = cur.next
        return count

    def travel(self):
        """遍歷鏈表"""
        cur = self._head
        while cur != None:
            print cur.item,
            cur = cur.next
        print ""
    def add(self, item):
        """頭部添加元素"""
        # 先創建一個保存item值的節點
        node = SingleNode(item)
        # 將新節點的鏈接域next指向頭節點,即_head指向的位置
        node.next = self._head
        # 將鏈表的頭_head指向新節點
        self._head = node
   def append(self, item):
        """尾部添加元素"""
        node = SingleNode(item)
        # 先判斷鏈表是否爲空,若是空鏈表,則將_head指向新節點
        if self.is_empty():
            self._head = node
        # 若不爲空,則找到尾部,將尾節點的next指向新節點
        else:
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node
	def insert(self, pos, item):
        """指定位置添加元素"""
        # 若指定位置pos爲第一個元素之前,則執行頭部插入
        if pos <= 0:
            self.add(item)
        # 若指定位置超過鏈表尾部,則執行尾部插入
        elif pos > (self.length()-1):
            self.append(item)
        # 找到指定位置
        else:
            node = SingleNode(item)
            count = 0
            # pre用來指向指定位置pos的前一個位置pos-1,初始從頭節點開始移動到指定位置
            pre = self._head
            while count < (pos-1):
                count += 1
                pre = pre.next
            # 先將新節點node的next指向插入位置的節點
            node.next = pre.next
            # 將插入位置的前一個節點的next指向新節點
            pre.next = node
   def remove(self,item):
        """刪除節點"""
        cur = self._head
        pre = None
        while cur != None:
            # 找到了指定元素
            if cur.item == item:
                # 如果第一個就是刪除的節點
                if not pre:
                    # 將頭指針指向頭節點的後一個節點
                    self._head = cur.next
                else:
                    # 將刪除位置前一個節點的next指向刪除位置的後一個節點
                    pre.next = cur.next
                break
            else:
                # 繼續按鏈表後移節點
                pre = cur
                cur = cur.next
    def search(self,item):
        """鏈表查找節點是否存在,並返回True或者False"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False

在這裏插入圖片描述
------單向循環鏈表:單鏈表的一個變形,鏈表中最後一個節點的next域不再爲None,而是指向鏈表的頭節點,其他的操作和單鏈表一樣

------雙向鏈表:一種更復雜的鏈表是“雙向鏈表”或“雙面鏈表”。每個節點有兩個鏈接:一個指向前一個節點,當此節點爲第一個節點時,指向空值;而另一個指向下一個節點,當此節點爲最後一個節點時,指向空值。

(13)棧
棧(stack),有些地方稱爲堆棧,是一種容器,可存入數據元素、訪問元素、刪除元素,它的特點在於只能允許在容器的一端(稱爲棧頂端指標,英語:top)進行加入數據(英語:push)和輸出數據(英語:pop)的運算。沒有了位置概念,保證任何時候可以訪問、刪除的元素都是此前最後存入的那個元素,確定了一種默認的訪問順序。由於棧數據結構只允許在一端進行操作,因而按照後進先出(LIFO, Last In First Out)的原理運作。
棧結構實現: 棧可以用順序表(用一個list就可以實現)實現,也可以用鏈表實現。

(14)隊列
隊列(queue)是隻允許在一端進行插入操作,而在另一端進行刪除操作的線性表。隊列是一種先進先出的(First In First Out)的線性表,簡稱FIFO。

隊列結構的實現:隊列、雙端隊列,均可以使用順序表來實現–一個list

以上就是基本的數據結構----接下來做算法了(樹、圖數據結構還沒有做)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章