1. 程式人生 > >常見資料結構與演算法整理總結(上)

常見資料結構與演算法整理總結(上)

資料結構是以某種形式將資料組織在一起的集合,它不僅儲存資料,還支援訪問和處理資料的操作。演算法是為求解一個問題需要遵循的、被清楚指定的簡單指令的集合。下面是自己整理的常用資料結構與演算法相關內容,如有錯誤,歡迎指出。

為了便於描述,文中涉及到的程式碼部分都是用Java語言編寫的,其實Java本身對常見的幾種資料結構,線性表、棧、佇列等都提供了較好的實現,就是我們經常用到的Java集合框架,有需要的可以閱讀這篇文章。Java - 集合框架完全解析

一、線性表
  1.陣列實現
  2.連結串列
二、棧與佇列
三、樹與二叉樹
  1.樹
  2.二叉樹基本概念
  3.二叉查詢樹
  4.平衡二叉樹
  5.紅黑樹
四、圖
五、總結

一、線性表

線性表是最常用且最簡單的一種資料結構,它是n個數據元素的有限序列。

實現線性表的方式一般有兩種,一種是使用陣列儲存線性表的元素,即用一組連續的儲存單元依次儲存線性表的資料元素。另一種是使用連結串列儲存線性表的元素,即用一組任意的儲存單元儲存線性表的資料元素(儲存單元可以是連續的,也可以是不連續的)。

陣列實現

陣列是一種大小固定的資料結構,對線性表的所有操作都可以通過陣列來實現。雖然陣列一旦建立之後,它的大小就無法改變了,但是當陣列不能再儲存線性表中的新元素時,我們可以建立一個新的大的陣列來替換當前陣列。這樣就可以使用陣列實現動態的資料結構。

  • 程式碼1 建立一個更大的陣列來替換當前陣列
int[] oldArray = new int[10];

int[] newArray = new int[20];

for (int i = 0; i < oldArray.length; i++) {
    newArray[i] = oldArray[i];
}

// 也可以使用System.arraycopy方法來實現陣列間的複製        
// System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);

oldArray = newArray;
  • 程式碼2 在陣列位置index上新增元素e
//oldArray 表示當前儲存元素的陣列
//size 表示當前元素個數
public void add(int index, int e) {

    if (index > size || index < 0) {
        System.out.println("位置不合法...");
    }

    //如果陣列已經滿了 就擴容
    if (size >= oldArray.length) {
        // 擴容函式可參考程式碼1
    }

    for (int i = size - 1; i >= index; i--) {
        oldArray[i + 1] = oldArray[i];
    }

    //將陣列elementData從位置index的所有元素往後移一位
    // System.arraycopy(oldArray, index, oldArray, index + 1,size - index);

    oldArray[index] = e;

    size++;
}

上面簡單寫出了陣列實現線性表的兩個典型函式,具體我們可以參考Java裡面的ArrayList集合類的原始碼。陣列實現的線性表優點在於可以通過下標來訪問或者修改元素,比較高效,主要缺點在於插入和刪除的花費開銷較大,比如當在第一個位置前插入一個元素,那麼首先要把所有的元素往後移動一個位置。為了提高在任意位置新增或者刪除元素的效率,可以採用鏈式結構來實現線性表。

連結串列

連結串列是一種物理儲存單元上非連續、非順序的儲存結構,資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列節點組成,這些節點不必在記憶體中相連。每個節點由資料部分Data和鏈部分Next,Next指向下一個節點,這樣當新增或者刪除時,只需要改變相關節點的Next的指向,效率很高。


單鏈表的結構

下面主要用程式碼來展示連結串列的一些基本操作,需要注意的是,這裡主要是以單鏈表為例,暫時不考慮雙鏈表和迴圈連結串列。

  • 程式碼3 連結串列的節點
class Node<E> {

    E item;
    Node<E> next;

    //建構函式
    Node(E element) {
       this.item = element;
       this.next = null;
   }
}
  • 程式碼4 定義好節點後,使用前一般是對頭節點和尾節點進行初始化
//頭節點和尾節點都為空 連結串列為空
Node<E> head = null;
Node<E> tail = null;
  • 程式碼5 空連結串列建立一個新節點
//建立一個新的節點 並讓head指向此節點
head = new Node("nodedata1");

//讓尾節點也指向此節點
tail = head;
  • 程式碼6 連結串列追加一個節點
//建立新節點 同時和最後一個節點連線起來
tail.next = new Node("node1data2");

//尾節點指向新的節點
tail = tail.next;
  • 程式碼7 順序遍歷連結串列
Node<String> current = head;
while (current != null) {
    System.out.println(current.item);
    current = current.next;
}
  • 程式碼8 倒序遍歷連結串列
static void printListRev(Node<String> head) {
//倒序遍歷連結串列主要用了遞迴的思想
    if (head != null) {
        printListRev(head.next);
        System.out.println(head.item);
    }
}
  • 程式碼 單鏈表反轉
//單鏈表反轉 主要是逐一改變兩個節點間的連結關係來完成
static Node<String> revList(Node<String> head) {

    if (head == null) {
        return null;
    }

    Node<String> nodeResult = null;

    Node<String> nodePre = null;
    Node<String> current = head;

    while (current != null) {

        Node<String> nodeNext = current.next;

        if (nodeNext == null) {
            nodeResult = current;
        }

        current.next = nodePre;
        nodePre = current;
        current = nodeNext;
    }

    return nodeResult;
}

上面的幾段程式碼主要展示了連結串列的幾個基本操作,還有很多像獲取指定元素,移除元素等操作大家可以自己完成,寫這些程式碼的時候一定要理清節點之間關係,這樣才不容易出錯。

連結串列的實現還有其它的方式,常見的有迴圈單鏈表,雙向連結串列,迴圈雙向連結串列。 迴圈單鏈表 主要是連結串列的最後一個節點指向第一個節點,整體構成一個鏈環。 雙向連結串列 主要是節點中包含兩個指標部分,一個指向前驅元,一個指向後繼元,JDK中LinkedList集合類的實現就是雙向連結串列。 迴圈雙向連結串列 是最後一個節點指向第一個節點。

二、棧與佇列

棧和佇列也是比較常見的資料結構,它們是比較特殊的線性表,因為對於棧來說,訪問、插入和刪除元素只能在棧頂進行,對於佇列來說,元素只能從佇列尾插入,從佇列頭訪問和刪除。

棧是限制插入和刪除只能在一個位置上進行的表,該位置是表的末端,叫作棧頂,對棧的基本操作有push(進棧)和pop(出棧),前者相當於插入,後者相當於刪除最後一個元素。棧有時又叫作LIFO(Last In First Out)表,即後進先出。


棧的模型

下面我們看一道經典題目,加深對棧的理解。


關於棧的一道經典題目

上圖中的答案是C,其中的原理可以好好想一想。

因為棧也是一個表,所以任何實現表的方法都能實現棧。我們開啟JDK中的類Stack的原始碼,可以看到它就是繼承類Vector的。當然,Stack是Java2前的容器類,現在我們可以使用LinkedList來進行棧的所有操作。

佇列

佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。


佇列示意圖

我們可以使用連結串列來實現佇列,下面程式碼簡單展示了利用LinkedList來實現佇列類。

  • 程式碼9 簡單實現佇列類
public class MyQueue<E> {

    private LinkedList<E> list = new LinkedList<>();

    // 入隊
    public void enqueue(E e) {
        list.addLast(e);
    }

    // 出隊
    public E dequeue() {
        return list.removeFirst();
    }
}

普通的佇列是一種先進先出的資料結構,而優先佇列中,元素都被賦予優先順序。當訪問元素的時候,具有最高優先順序的元素最先被刪除。優先佇列在生活中的應用還是比較多的,比如醫院的急症室為病人賦予優先順序,具有最高優先順序的病人最先得到治療。在Java集合框架中,類PriorityQueue就是優先佇列的實現類,具體大家可以去閱讀原始碼。

三、樹與二叉樹

樹型結構是一類非常重要的非線性資料結構,其中以樹和二叉樹最為常用。在介紹二叉樹之前,我們先簡單瞭解一下樹的相關內容。

是由n(n>=1)個有限節點組成一個具有層次關係的集合。它具有以下特點:每個節點有零個或多個子節點;沒有父節點的節點稱為節點;每一個非根節點有且只有一個 父節點 ;除了根節點外,每個子節點可以分為多個不相交的子樹。


樹的結構

二叉樹基本概念

  • 定義

二叉樹是每個節點最多有兩棵子樹的樹結構。通常子樹被稱作“左子樹”和“右子樹”。二叉樹常被用於實現二叉查詢樹和二叉堆。

  • 相關性質

二叉樹的每個結點至多隻有2棵子樹(不存在度大於2的結點),二叉樹的子樹有左右之分,次序不能顛倒。

二叉樹的第i層至多有2^(i-1)個結點;深度為k的二叉樹至多有2^k-1個結點。

一棵深度為k,且有2^k-1個節點的二叉樹稱之為 滿二叉樹

深度為k,有n個節點的二叉樹,當且僅當其每一個節點都與深度為k的滿二叉樹中,序號為1至n的節點對應時,稱之為 完全二叉樹


  • 三種遍歷方法

在二叉樹的一些應用中,常常要求在樹中查詢具有某種特徵的節點,或者對樹中全部節點進行某種處理,這就涉及到二叉樹的遍歷。二叉樹主要是由3個基本單元組成,根節點、左子樹和右子樹。如果限定先左後右,那麼根據這三個部分遍歷的順序不同,可以分為先序遍歷、中序遍歷和後續遍歷三種。

(1) 先序遍歷 若二叉樹為空,則空操作,否則先訪問根節點,再先序遍歷左子樹,最後先序遍歷右子樹。 (2) 中序遍歷 若二叉樹為空,則空操作,否則先中序遍歷左子樹,再訪問根節點,最後中序遍歷右子樹。(3) 後序遍歷 若二叉樹為空,則空操作,否則先後序遍歷左子樹訪問根節點,再後序遍歷右子樹,最後訪問根節點。


給定二叉樹寫出三種遍歷結果
  • 樹和二叉樹的區別

(1) 二叉樹每個節點最多有2個子節點,樹則無限制。 (2) 二叉樹中節點的子樹分為左子樹和右子樹,即使某節點只有一棵子樹,也要指明該子樹是左子樹還是右子樹,即二叉樹是有序的。 (3) 樹決不能為空,它至少有一個節點,而一棵二叉樹可以是空的。

上面我們主要對二叉樹的相關概念進行了介紹,下面我們將從二叉查詢樹開始,介紹二叉樹的幾種常見型別,同時將之前的理論部分用程式碼實現出來。

二叉查詢樹

  • 定義

二叉查詢樹就是二叉排序樹,也叫二叉搜尋樹。二叉查詢樹或者是一棵空樹,或者是具有下列性質的二叉樹: (1) 若左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;(2) 若右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;(3) 左、右子樹也分別為二叉排序樹;(4) 沒有鍵值相等的結點。


典型的二叉查詢樹的構建過程
  • 效能分析

對於二叉查詢樹來說,當給定值相同但順序不同時,所構建的二叉查詢樹形態是不同的,下面看一個例子。


不同形態平衡二叉樹的ASL不同

可以看到,含有n個節點的二叉查詢樹的平均查詢長度和樹的形態有關。最壞情況下,當先後插入的關鍵字有序時,構成的二叉查詢樹蛻變為單支樹,樹的深度為n,其平均查詢長度(n+1)/2(和順序查詢相同),最好的情況是二叉查詢樹的形態和折半查詢的判定樹相同,其平均查詢長度和log2(n)成正比。平均情況下,二叉查詢樹的平均查詢長度和logn是等數量級的,所以為了獲得更好的效能,通常在二叉查詢樹的構建過程需要進行“平衡化處理”,之後我們將介紹平衡二叉樹和紅黑樹,這些均可以使查詢樹的高度為O(log(n))。

  • 程式碼10 二叉樹的節點
class TreeNode<E> {

    E element;
    TreeNode<E> left;
    TreeNode<E> right;

    public TreeNode(E e) {
        element = e;
    }
}

二叉查詢樹的三種遍歷都可以直接用遞迴的方法來實現:

  • 程式碼12 先序遍歷
protected void preorder(TreeNode<E> root) {

    if (root == null)
        return;

    System.out.println(root.element + " ");

    preorder(root.left);

    preorder(root.right);
}
  • 程式碼13 中序遍歷
protected void inorder(TreeNode<E> root) {

    if (root == null)
        return;

    inorder(root.left);

    System.out.println(root.element + " ");

    inorder(root.right);
}
  • 程式碼14 後序遍歷
protected void postorder(TreeNode<E> root) {

    if (root == null)
        return;

    postorder(root.left);

    postorder(root.right);

    System.out.println(root.element + " ");
}
  • 程式碼15 二叉查詢樹的簡單實現
/**
 * @author JackalTsc
 */
public class MyBinSearchTree<E extends Comparable<E>> {

    // 根
    private TreeNode<E> root;

    // 預設建構函式
    public MyBinSearchTree() {
    }

    // 二叉查詢樹的搜尋
    public boolean search(E e) {

        TreeNode<E> current = root;

        while (current != null) {

            if (e.compareTo(current.element) < 0) {
                current = current.left;
            } else if (e.compareTo(current.element) > 0) {
                current = current.right;
            } else {
                return true;
            }
        }

        return false;
    }

    // 二叉查詢樹的插入
    public boolean insert(E e) {

        // 如果之前是空二叉樹 插入的元素就作為根節點
        if (root == null) {
            root = createNewNode(e);
        } else {
            // 否則就從根節點開始遍歷 直到找到合適的父節點
            TreeNode<E> parent = null;
            TreeNode<E> current = root;
            while (current != null) {
                if (e.compareTo(current.element) < 0) {
                    parent = current;
                    current = current.left;
                } else if (e.compareTo(current.element) > 0) {
                    parent = current;
                    current = current.right;
                } else {
                    return false;
                }
            }
            // 插入
            if (e.compareTo(parent.element) < 0) {
                parent.left = createNewNode(e);
            } else {
                parent.right = createNewNode(e);
            }
        }
        return true;
    }

    // 建立新的節點
    protected TreeNode<E> createNewNode(E e) {
        return new TreeNode(e);
    }

}

// 二叉樹的節點
class TreeNode<E extends Comparable<E>> {

    E element;
    TreeNode<E> left;
    TreeNode<E> right;

    public TreeNode(E e) {
        element = e;
    }
}

上面的程式碼15主要展示了一個自己實現的簡單的二叉查詢樹,其中包括了幾個常見的操作,當然更多的操作還是需要大家自己去完成。因為在二叉查詢樹中刪除節點的操作比較複雜,所以下面我詳細介紹一下這裡。

  • 二叉查詢樹中刪除節點分析

要在二叉查詢樹中刪除一個元素,首先需要定位包含該元素的節點,以及它的父節點。假設current指向二叉查詢樹中包含該元素的節點,而parent指向current節點的父節點,current節點可能是parent節點的左孩子,也可能是右孩子。這裡需要考慮兩種情況:

  1. current節點沒有左孩子,那麼只需要將patent節點和current節點的右孩子相連。
  2. current節點有一個左孩子,假設rightMost指向包含current節點的左子樹中最大元素的節點,而parentOfRightMost指向rightMost節點的父節點。那麼先使用rightMost節點中的元素值替換current節點中的元素值,將parentOfRightMost節點和rightMost節點的左孩子相連,然後刪除rightMost節點。
    // 二叉搜尋樹刪除節點
    public boolean delete(E e) {

        TreeNode<E> parent = null;
        TreeNode<E> current = root;

        // 找到要刪除的節點的位置
        while (current != null) {
            if (e.compareTo(current.element) < 0) {
                parent = current;
                current = current.left;
            } else if (e.compareTo(current.element) > 0) {
                parent = current;
                current = current.right;
            } else {
                break;
            }
        }

        // 沒找到要刪除的節點
        if (current == null) {
            return false;
        }

        // 考慮第一種情況
        if (current.left == null) {
            if (parent == null) {
                root = current.right;
            } else {
                if (e.compareTo(parent.element) < 0) {
                    parent.left = current.right;
                } else {
                    parent.right = current.right;
                }
            }
        } else { // 考慮第二種情況
            TreeNode<E> parentOfRightMost = current;
            TreeNode<E> rightMost = current.left;
            // 找到左子樹中最大的元素節點
            while (rightMost.right != null) {
                parentOfRightMost = rightMost;
                rightMost = rightMost.right;
            }

            // 替換
            current.element = rightMost.element;

            // parentOfRightMost和rightMost左孩子相連
            if (parentOfRightMost.right == rightMost) {
                parentOfRightMost.right = rightMost.left;
            } else {
                parentOfRightMost.left = rightMost.left;
            }
        }

        return true;
    }

平衡二叉樹

平衡二叉樹又稱AVL樹,它或者是一棵空樹,或者是具有下列性質的二叉樹:它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過1。


平衡二叉樹

AVL樹是最先發明的自平衡二叉查詢樹演算法。在AVL中任何節點的兩個兒子子樹的高度最大差別為1,所以它也被稱為高度平衡樹,n個結點的AVL樹最大深度約1.44log2n。查詢、插入和刪除在平均和最壞情況下都是O(log n)。增加和刪除可能需要通過一次或多次樹旋轉來重新平衡這個樹。

紅黑樹

紅黑樹是平衡二叉樹的一種,它保證在最壞情況下基本動態集合操作的事件複雜度為O(log n)。紅黑樹和平衡二叉樹區別如下:(1) 紅黑樹放棄了追求完全平衡,追求大致平衡,在與平衡二叉樹的時間複雜度相差不大的情況下,保證每次插入最多隻需要三次旋轉就能達到平衡,實現起來也更為簡單。(2) 平衡二叉樹追求絕對平衡,條件比較苛刻,實現起來比較麻煩,每次插入新節點之後需要旋轉的次數不能預知。點選檢視更多

四、圖

  • 簡介

圖是一種較線性表和樹更為複雜的資料結構,線上性表中,資料元素之間僅有線性關係,在樹形結構中,資料元素之間有著明顯的層次關係,而在圖形結構中,節點之間的關係可以是任意的,圖中任意兩個資料元素之間都可能相關。圖的應用相當廣泛,特別是近年來的迅速發展,已經滲入到諸如語言學、邏輯學、物理、化學、電訊工程、電腦科學以及數學的其他分支中。

  • 相關閱讀

因為圖這部分的內容還是比較多的,這裡就不詳細介紹了,有需要的可以自己搜尋相關資料。

五、總結

到這裡,關於常見的資料結構的整理就結束了,斷斷續續大概花了兩天時間寫完,在總結的過程中,通過查閱相關資料,結合書本內容,收穫還是很大的,在下一篇部落格中將會介紹常用資料結構與演算法整理總結(下)之演算法篇,歡迎大家關注。

相關推薦

常見資料結構演算法整理總結(

資料結構是以某種形式將資料組織在一起的集合,它不僅儲存資料,還支援訪問和處理資料的操作。演算法是為求解一個問題需要遵循的、被清楚指定的簡單指令的集合。下面是自己整理的常用資料結構與演算法相關內容,如有錯誤,歡迎指出。 為了便於描述,文中涉及到的程式碼部分都是用Java語言編寫的,其實Java本身對常見的幾種資

常見資料結構演算法整理總結(下)

這篇文章是常見資料結構與演算法整理總結的下篇,上一篇主要是對常見的資料結構進行集中總結,這篇主要是總結一些常見的演算法相關內容,文章中如有錯誤,歡迎指出。 一、概述 二、查詢演算法 三、排序演算法 四、其它演算法 五、常見演算法題 六、總結一、概述以前看到這樣一句話,語言只是工具,演算法才是程式設計的靈魂。的

常見資料結構演算法整理總結

資料結構是以某種形式將資料組織在一起的集合,它不僅儲存資料,還支援訪問和處理資料的操作。演算法是為求解一個問題需要遵循的、被清楚指定的簡單指令的集合。下面是自己整理的常用資料結構與演算法相關內容,如有錯誤,歡迎指出。 為了便於描述,文中涉及到的程式碼部分都是用Java語言編寫的,其實Java本身對常見的幾種

前端學習總結(二十二——常見資料結構演算法javascript實現

寫在前面 作為前端開發者而言,可能不會像後端開發那樣遇到很多的演算法和資料結構問題,但是不論是做前端、 服務端還是客戶端, 任何一個程式設計師都會開始面對更加複雜的問題, 這個時候演算法和資料結構知識就變得不可或缺,它是程式設計能力中很重要的一部分。 如今的

go語言-常見資料結構演算法

選擇排序 //基礎版 func SelectionSort(arr []int, n int) { for i := 0; i < n; i ++ { minindex := i for j := i + 1; j < n; j++ { if arr[minindex

[一步步學資料結構演算法 11]-排序()

一、排序方法與複雜度歸類 (1)幾種最經典、最常用的排序方法:氣泡排序、插入排序、選擇排序、快速排序、歸併排序、計數排序、基數排序、桶排序。 (2)複雜度歸類 氣泡排序、插入排序、選擇排序 O(n^2) 快速排序、歸併排序 O(nlogn) 計數排序、基數排序、

資料結構演算法-連結串列()

陣列是軟體開發過程中非常重要的一種資料結構,但是陣列至少有兩個侷限: 編譯期需要確定元素大小 陣列在記憶體中是連續的,插入或者刪除需要移動陣列中其他資料 陣列適合處理確定長度的,對於插入或者刪除不敏感的資料。如果資料是頻繁變化的,就需要選擇其他資料結構了。連結串列是一種邏輯簡單的、實用的資料結構,

資料結構演算法學習總結(一

1.什麼是資料結構和演算法 資料結構,就是一組資料的儲存結構。演算法,就是操作資料的一組方法。資料結構是為演算法服務的,演算法要作用在特定的資料結構之上。 2.為什麼要學習資料結構和演算法? (1)對個人:資料結構和演算法是程式設計師的必修課程之一,能幫助我們寫出效能更

資料結構演算法學習總結-線性表的順序儲存實現

  線性表的順序儲存是用一組地址連續的儲存單元一次儲存線性表的資料元素。 1.線性表的順序儲存   假設線性表的每個資料元素需佔用K個儲存單元,並以元素所佔的第一個儲存單元的地址作為資料元素的儲存地址。則線性表中序號為i的資料元素的儲存地址LOC(ai)

資料結構演算法整理

    基本上耳熟能詳的2個概念了,之前總是趕到招聘的時候,才會折騰翻一下,總覺得沒什麼用,但是隨著工作以及網上的閱讀,發現,其實,用處真的是太大了。     好早之前就買了《演算法導論》這部鉅著,然而,現在依然束之高閣,最近想著從簡單點的看起,於是翻了翻《大話資料結構》《

資料結構演算法學習總結(二

1.什麼是複雜度分析? (1)資料結構和演算法解決是“如何讓計算機更快時間、更省空間的解決問題”。 (2)因此需要從執行時間和佔用空間兩個維度來評估資料結構和演算法的效能。 (3)分別用時間複雜度和空間複雜度兩個概念描述效能問題,二者統稱為複雜度。 (4)複雜度描述的

Java進階專題(十六) 資料結構演算法的應用()

# 前言 ​ 學習演算法,我們不需要死記硬背那些冗長複雜的背景知識、底層原理、指令語法……需要做的是領悟演算法思想、理解演算法對記憶體空間和效能的影響,以及開動腦筋去尋求解決問題的最佳方案。相比程式設計領域的其他技術,演算法更純粹,更接近數學,也更具有趣味性。 ​ 本文將回顧資料結構與演算法的基礎知識,學

為什麼我要放棄javaScript資料結構演算法(第一章—— JavaScript簡介

資料結構與演算法一直是我算比較薄弱的地方,希望通過閱讀《javaScript資料結構與演算法》可以有所改變,我相信接下來的記錄不單單對於我自己有幫助,也可以幫助到一些這方面的小白,接下來讓我們一起學習。 第一章 JavaScript簡介 眾所周知,JavaScript是一門非常強大的程式語言,不僅可以用於

資料結構演算法入門(1

一、資料結構 資料之間相互存在的一種或多種特定的關係的元素的集合。 邏輯結構 資料物件中資料元素之間的相互關係 1.集合結構 在資料結構中,如果不考慮資料元素之間的關係,這種結構稱為集合結構。 各個元素是平等的,共同屬性是屬於同一個集合 2.線性結構 線性結構中的資料元素之間

面試專題資料資料結構演算法、通訊協議

一、通訊協議 一、三次握手簡單例子 第一次握手: A給B打電話說,你可以聽到我說話嗎? 第二次握手: B收到了A的資訊,然後對A說: 我可以聽得到你說話啊,你能聽得到我說話嗎?   第三次握手: A收到了B的資訊,然後說可以的,我要給你發信息啦! 對圖說明:

資料結構演算法筆記(二複雜度分析

2. 複雜度分析 2.1 什麼是複雜度分析 資料結構和演算法的本質:快和省,如何讓程式碼執行得更快、更省儲存空間。 演算法複雜度分為時間複雜度和空間複雜度,從執行時間和佔用空間兩個維度來評估資料結構和演算法的效能。 複雜度描述的是演算法執行時間(或佔用空間)與資料規模的增長關

資料結構演算法筆記(三陣列

3.陣列 陣列(Array)是一種線性表資料結構。它是一組連續的記憶體空間,來儲存一組具有相同型別的資料。 3.1 特性 線性表 資料排成像一條線的結構,如陣列、連結串列、佇列、棧等。 與之相對立的是非線性,如二叉樹、堆、圖等,其資料之間並不是簡單的前後關係。

資料結構演算法筆記(三反轉部分連結串列

反轉部分連結串列 上次我們搞定了反轉單向連結串列和雙向連結串列的問題,但實際過程中我們可能只要反轉部分連結串列,在這種情況下我們需要對上次寫出的類增加一個叫做reverse_part_linklist的函式,傳入引數為兩個整數from和to,將from到to之間的節點進行反轉

javascript資料結構演算法筆記(一:棧

javascript資料結構與演算法筆記(一):棧 一:簡介 二:ES6版Stack類(陣列) 三:ES版Stack類私有屬性的封裝 1.偽私有屬性封裝 2.真私有屬性封裝

資料結構演算法 部分題目(字串

1.求陣列中兩個字串的最小距離 題目: 給定一個數組 strs,其中的資料都是字串,給定兩個字串 str1,str2。如果這兩個字串都在 strs陣列中,就返回它們之間的最小距離;如果其中任何一個不在裡面,則返回 -1;如果兩個字串相等,則返回 0。 例如:給定[‘*’,’3’,’*’,’5’,