国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

數(shù)據(jù)結(jié)構(gòu)分析及其實現(xiàn)(Stack、Queue、Tree、LinkedList)

Richard_Gao / 1230人閱讀

摘要:常見數(shù)據(jù)結(jié)構(gòu)分析及實現(xiàn)說明本文中的代碼是參考編程思想某培訓(xùn)機構(gòu)。同時還要分析這些數(shù)據(jù)結(jié)構(gòu)在時間和空間上的開銷。這種專門研究應(yīng)用程序中的數(shù)據(jù)之間的邏輯關(guān)系,存儲方式及其操作的學(xué)問就是數(shù)據(jù)結(jié)構(gòu)。

常見數(shù)據(jù)結(jié)構(gòu)分析及實現(xiàn) 說明

本文中的代碼是參考《Java編程思想》、某培訓(xùn)機構(gòu)。

文中的代碼放Github了,有興趣的可以看看,點歌star鼓勵下我。

代碼在Sublime中敲的,坑爹的GBK,注釋了很多中文,一轉(zhuǎn)碼不能用了!!!

重點在思想,而不是實現(xiàn) 。再次推薦《Java編程思想》。

1、數(shù)據(jù)結(jié)構(gòu)

編程的本質(zhì)就是對數(shù)據(jù)(信息以數(shù)據(jù)的形式而存在)的處理,實際編程中不得不處理大量數(shù)據(jù),因此實際動手編程之前必須先分析處理這些數(shù)據(jù),處理數(shù)據(jù)之間存在的關(guān)系。

現(xiàn)實的數(shù)據(jù)元素之間有個錯綜復(fù)雜的邏輯關(guān)系,需要采用合適的物理結(jié)構(gòu)來存儲這些數(shù)據(jù),并以此為基礎(chǔ)對這些數(shù)據(jù)進行相應(yīng)的操作。同時還要分析這些數(shù)據(jù)結(jié)構(gòu)在時間和空間上的開銷。這種專門研究應(yīng)用程序中的數(shù)據(jù)之間的邏輯關(guān)系,存儲方式及其操作的學(xué)問就是數(shù)據(jù)結(jié)構(gòu)。

數(shù)據(jù)元素之間存在的關(guān)聯(lián)關(guān)系被稱為數(shù)據(jù)的邏輯結(jié)構(gòu),歸納起來,大致有如下四種基本的邏輯結(jié)構(gòu):

集合:數(shù)據(jù)元素之間只有"同屬于一個集合"的關(guān)系

線性關(guān)系:數(shù)據(jù)元素之間存在一個對一個的關(guān)系

樹形結(jié)構(gòu):數(shù)據(jù)元素之間存在一個對多個的關(guān)系

圖狀結(jié)構(gòu)或網(wǎng)狀結(jié)構(gòu):數(shù)據(jù)元素之間存在多個對多個的關(guān)系。

腦補圖:

圖片>代碼>文字,個人理解,能用圖片說明問題的就不要用代碼,同理,盡量用代碼+文字解釋問題的本質(zhì)。

同一種的邏輯結(jié)構(gòu),在底層通常有兩種物理存儲結(jié)構(gòu):

順序存儲結(jié)構(gòu),如一維數(shù)組

非順序存儲結(jié)構(gòu),如鏈式存儲結(jié)構(gòu)(鏈表)、散列

順序結(jié)構(gòu)適合讀操作(為啥呢?因為有索引啊),鏈表存儲適合寫操作(為啥呢?斷開,加上節(jié)點就完成,不需要底層復(fù)制啊)

算法的設(shè)計取決于邏輯結(jié)構(gòu):算法的實現(xiàn)依賴于存儲結(jié)構(gòu)。對象的設(shè)計取決于類結(jié)構(gòu),(...)

什么是數(shù)據(jù)結(jié)果呢?數(shù)據(jù)結(jié)構(gòu)歸納起來所要研究的問題就三方面:

數(shù)據(jù)元素之間的客觀聯(lián)系(邏輯結(jié)構(gòu))

數(shù)據(jù)在計算機內(nèi)部的存儲方式(存儲結(jié)構(gòu))

針對數(shù)據(jù)實施的有效的操作和處理(算法)

對象之間的關(guān)系(對現(xiàn)實的抽象,繼承?組合?),存儲在內(nèi)存中哪里,堆上啊,怎么存?存在數(shù)組里?hash表里?怎么處理的啊?增刪改查啊,排序那,加密解密啊,

Stack

對于普通的線性表而言,它的作用是一個容器,用于裝具有相似結(jié)果的數(shù)據(jù)。

分為順序存儲機構(gòu)和鏈式存儲結(jié)構(gòu)

可以進行插入、刪除和排序的操作

如果線性表之允許在線性表的某端添加、刪除元素,這時就演變?yōu)椋簵:完犃小?先進后出(彈夾),先進先出(火車站排隊))

以下圖片來自維基百科(百X百科就別看了)

原諒沒放恐怖的,來自Google(百X就別用了)

棧(Stack),是一種特殊的線性表,只能在固定的一端(線性表的尾端)進行插入、刪除操作。

允許進行插入、刪除操作的一端為棧頂(top),另一端,你猜?(bottom)

進棧:將一個元素插入棧的過程,棧的長度+1,(壓入子彈)

出棧:刪除一個元素的過程,棧的長度-1.(彈出發(fā)射...)

先進后出,或者說后進先出。

常用操作:初始化,(隨著棧幀的移除,方法在執(zhí)行。可能出現(xiàn)https://stackoverflow.com/),++i,i++,

在Java中繼承關(guān)系,Stack繼承自Vector,List,(abstractList?)

需求:
請編寫代碼實現(xiàn)Stack類,該類能夠?qū)崿F(xiàn)后進先出的堆棧功能,要求實現(xiàn)的方法包括:

Stack(int) 實例化指定深度的棧

boolean push(E item) 像棧頂壓入對象,成功返回true,棧已滿返回false

E pop() 從棧頂移除對象并返回,為空則返回null

E peek() 查看并返回棧頂?shù)膶ο螅瑸榭辗祷豱ull

int size() 返回棧中當前元素數(shù)量

int depth() 返回當前堆棧深度

-
萬惡的字符編碼,無比的郁悶以下所有代碼參考網(wǎng)絡(luò),在Sublime中編寫。

基于單列表實現(xiàn):

class Node {
    Node next = null;
    E data;
    public Node(E data) {
        this.data = data;
    }
}

//采用單鏈表實現(xiàn)棧
public class MyStack {
    int depth;   //棧的深度

    public MyStack(int i) {
        this.depth = i;
    }

    Node top = null;

    //將元素壓入棧中
    public boolean push(E data) {
        if(size() < depth) {
        Node newNode = new Node(data);
        newNode.next = top;
        top = newNode;
        return true;
        }
        return false;
    }

    //讀取棧中的頭節(jié)點,不刪除頭節(jié)點

    public E peek() {
        if(top ==null) {
            return null;
        }
        return top.data;
    }

    //獲取棧中的頭節(jié)點,并刪除頭節(jié)點
    public E pop() {
        if(top ==null) {
            return null;
        }
        Node tmp = top;
        top = top.next;
        return tmp.data;
    }
    //棧的元素個數(shù)

    public int size() {
        int len = 0;
        Node tmeNode = top;
        while(tmeNode != null) {
            tmeNode = tmeNode.next;
            len++;
        }
        return len;
    }

    //當前棧的深度
    public int depth() {
        return this.depth;
    }
    public static void main(String[] args) {
      MyStack stack = new MyStack(2);
      System.out.println(stack.push(1));
      System.out.println(stack.push(2));
      System.out.println(stack.push(3));
      System.out.println("棧的元素個數(shù): " +stack.size());
      System.out.println(stack.pop());
      System.out.println(stack.pop());
      System.out.println(stack.pop());
      System.out.println("棧的元素個數(shù): " + stack.depth());
    }
}
---------------------------此代碼來自《Java編程思想》----------------------------------
import java.util.LinkedList;

public class Stack {
  private LinkedList storage = new LinkedList();
  public void push(T v) { storage.addFirst(v); }
  public T peek() { return storage.getFirst(); }
  public T pop() { return storage.removeFirst(); }
  public boolean empty() { return storage.isEmpty(); }
  public String toString() { return storage.toString(); }
}

在來看看大佬的另一種實現(xiàn),簡單明了啊。

public class LinkedStack {

    private static class Node {
        U item;
        Node next;
        Node() {
            item = null;
            next =null;
        }
        Node(U item,Node next) {
            this.item = item;
            this.next = next;
        }
        boolean end() {
            return item == null && next == null;
        }
    }

    private Node top = new Node();

    public void push(T item) {
        top = new Node(item,top);
    }

    public T pop() {
        T result = top.item;
        if (!top.end()) {
            top = top.next;
        }
        return result;
    }

    public static void main(String[] args) {
        LinkedStack lss = new LinkedStack();
        for (String s : "Phasers on stun!".split(" ") )
            lss.push(s);

        String s;
        while((s = lss.pop()) != null)
            System.out.println(s);
    }
}
輸出如下:
I:Java
otesortcode>java LinkedStack
stun!
on
Phasers
Queue

隊列(queue),也是一種特殊的線性表,使用固定的一端來插入數(shù)據(jù),另一端用于刪除數(shù)據(jù)

先進先出,就像火車站排隊買票一樣!!!,整個隊伍向前面移動。

分為順序隊列結(jié)構(gòu)和鏈式隊列結(jié)構(gòu)

從JDK 5 開始,Java集合框架提供了Queue接口,實現(xiàn)該接口的類可以當成隊列使用,如LinkedBlockingQueue,PriorityBlockingQueue。

可以通過輪詢和等待-通知機制實現(xiàn)阻塞隊列。

具體Queue實現(xiàn):

import java.util.*;

public class SimpleQueue implements Iterable {
    private LinkedList storage = new LinkedList();
    public void add(T t){
        storage.offer(t);
    }
    public T get() {
        return storage.poll();
    }
    public Iterator iterator() {
        return storage.iterator();
    }

    public static void main(String[] args) {
        SimpleQueue queue = new SimpleQueue();
        queue.add(8);
        System.out.println(queue.get());
    }
}

我們在來看看用Stack如何實現(xiàn)Queue,非常不錯,《Java編程思想》

import java.util.Stack;

 public class MyQueue{
    Stack stack = new Stack();
    Stack stackTmp = new Stack();

    //Push element X to the back of queue
    public void push(int x) {
        stack.push(x);
    }

    //Removes the element form in front of queue
    public void pop() {
        if (stackTmp.isEmpty()) {
            while (!stack.isEmpty()) {
                int tmp = stack.peek();
                stackTmp.push(tmp);
                stack.pop();
            }
        }
        else {
            stackTmp.pop();
        }
    }

    //Get the front element
    public int peek() {
        if (!stackTmp.isEmpty()) {
            int tmp = stack.peek();
            stackTmp.push(tmp);
        }
        return stackTmp.peek();
    }

    //Return whether the queueis empty
    public boolean empty() {
        if (stackTmp.isEmpty() && stack.isEmpty()) {
            return true;
        }else {
            return false;
        }
    }

    public static void main(String[] args) {
        MyQueue queue = new MyQueue();
        queue.push(8);
        System.out.println(queue.empty());     //false
    }
}
Tree

樹,也是一種數(shù)據(jù)結(jié)構(gòu),非線性的,這種結(jié)構(gòu)內(nèi)的元素存在一對多的關(guān)系。

樹,尤其是二叉樹應(yīng)用很廣泛,排序二叉樹,平衡二叉樹,紅黑樹。

二叉樹,在普通的樹的基礎(chǔ)上,讓一顆樹中每個節(jié)點最多只能包含兩個子節(jié)點,且嚴格區(qū)分左子節(jié)點和右子節(jié)點(位置不能變化)
-遍歷二叉樹,考慮深讀,優(yōu)先遍歷。(先序遍歷、中序遍歷、后續(xù)遍歷)和廣度優(yōu)先遍歷。

哈夫曼樹,一種帶權(quán)路徑最短的二叉樹,在信息檢索中非常有用

哈夫曼編碼,假設(shè)需要對一個字符串如“abcabcabc”進行編碼,將它轉(zhuǎn)化為唯一的二進制碼,同時要求轉(zhuǎn)換出來的二進制碼的長度最小。可以采用哈夫曼樹來解決報文編碼問題

排序二叉樹:一種特殊的二叉樹,可以非常方便的對樹中的所有節(jié)點進行排序和檢索。

二叉樹,這里采用遞歸和內(nèi)部類的思想。

public class BinaryTree {
    private Node root;

    //添加節(jié)點
    public void add(int data) {
        if (root ==null) {
            root = new Node(data);
        }else {
            root.addNode(data);
        }
    }
    //打印節(jié)點
    public void print() {
        root.printNode();
    }

    private class Node {
        private int data;
        private Node left;
        private Node right;

        public Node(int data) {
            this.data = data;
        }

        public void addNode(int data) {
            //核心思想就是進來先個當前節(jié)點比,如果如果小于則在左邊添加,如果左邊沒子節(jié)點,則創(chuàng)建,如果有添加
            if (this.data > data) {
                if (this.left == null) {
                    this.left = new Node(data);
                }else {
                    this.addNode(data);    //這里應(yīng)該是采用遞歸。
                }
            }else {
                if (this.right == null) {
                    this.right = new Node(data);
                }else {
                    this.right.addNode(data);
                }
            }
        }

        //中序遍歷
        public void printNode() {
            if (this.left != null) {
                this.left.printNode();
            }
            System.out.println(this.data + "->");
            if (this.right !=null) {
                this.right.printNode();
            }
        }
    }
}
------------------------測試-----------------------------------------------
public static void main(String[] args) {

  BinaryTree bt = new BinaryTree();
  // 8、3、10、1、6、14、4、7、13
  bt.add(8);bt.add(3);bt.add(10);
  bt.add(1);bt.add(6);bt.add(14);
  bt.add(4);bt.add(7);bt.add(13);
  bt.print();
}
輸出:
1->3->4->6->7->8->10->13->14->
LinkedList

ArrayList因為亂碼,寫了一半,無奈啊,完全坑我,其思想就是根據(jù)索引,涉及到擴容,判斷越界了么,。這里先不管了。直接看LinkedList。

public class MyLinkedList {
    protected Node first;    // 鏈表的第一個節(jié)點
    protected Node last;    // 鏈表的最后一個節(jié)點
    private int size;    // 節(jié)點的數(shù)量

    // 鏈表中的每一個節(jié)點
    public class Node {
        public Node(Object ele) {
            this.ele = ele;
        }

        Node prev;                // 上一個節(jié)點對象
        Node next;                // 下一個節(jié)點對象
        public Object ele; // 當前節(jié)點中存儲的數(shù)據(jù)
    }

    public void addFirst(Object ele) {
        Node node = new Node(ele);      //需要保存的節(jié)點對象
        //進來一個節(jié)點,如果為空的話,它可定時第一個,也是最后一個
        if (size == 0) {
            this.first = node;
            this.last = node;
        }else {
            node.next = this.first;                // 把之前第一個作為新增節(jié)點的下一個節(jié)點,(進來一個,當前的只能當老二了。)
            this.first.prev = node;                // 把新增節(jié)點作為之前第一個節(jié)點的上一個節(jié)點
            this.first = node;                    // 把新增的節(jié)點作為第一個節(jié)點
        }
        size++;
  }
     //這里很重要,別忘記
    public void addLast(Object ele) {
        Node node = new Node(ele);
        if (size == 0) {
            this.first = node;
            this.last = node;
        }else {
            this.last.next = node;            // 新增節(jié)點作為之前最后一個節(jié)點的下一個節(jié)點(因為是加在后面,所以當前節(jié)點的下一個才是 新增節(jié)點)
            node.prev = this.last;            // 之前最后一個節(jié)點作為新增節(jié)點的上一個節(jié)點
            this.last = node;                // 把新增的節(jié)點作為最后一個節(jié)點
        }
    }
    //原諒我復(fù)制了
    public void remove(Object ele) {
        // 找到被刪除的節(jié)點
        Node current = this.first;// 確定為第一個節(jié)點,從頭到尾開始找
        for (int i = 0; i < size; i++) {
            if (!current.ele.equals(ele)) {// 當前為true !true 為false ,說明找到當前ele,輸出
                if (current.next == null) { // 續(xù)上: 如果false取反為true, 判斷是否最后一個,
                    return;
                }
                current = current.next;
            }
        }
        //刪除節(jié)點
        if(current==first){
            this.first = current.next; //當前的下一個作為第一個
            this.first.prev = null; //當前下一個對上一個的引用設(shè)置為null

        }else if(current==last){
            this.last = current.prev;
            this.last.next = null;
        }else{
            //把刪除當前節(jié)點的下一個節(jié)點作為刪除節(jié)點的上一個節(jié)點的next
            current.prev.next =current.next;
            //把刪除節(jié)點的上一個節(jié)點作為刪除節(jié)點下一個節(jié)點的prev
            current.next.prev = current.prev;

        }
        size--;
        //System.out.println("current =" + current.ele);
    }

    public String toString() {
        if (size == 0) {
            return "[]";
        }
        StringBuilder sb = new StringBuilder(size * 2 + 1);
        Node current = this.first;// 第一個節(jié)點
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(current.ele);
            if (i != size - 1) {
                sb.append(",");
            } else {
                sb.append("]");
            }
            current = current.next; // 獲取自己的下一個節(jié)點
        }
        return sb.toString();
    }
}

這個雙向列表有點難理解,還是看圖吧,

線性鏈表:

雙向鏈表:

先到這里吧,gogogo,機會是留給有準備的人,

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/68685.html

相關(guān)文章

  • 二叉樹

    摘要:完全二叉樹深度為有個結(jié)點的二叉樹,其每個結(jié)點的編號與深度為的滿二叉樹中編號從的結(jié)點一一對應(yīng)葉子結(jié)點只可能在層數(shù)最大的兩層上出現(xiàn)。 二叉樹的性質(zhì) (1) 在二叉樹的第 i 層最多有 2^i-1 個結(jié)點 (i>=1). (2) 深度為 k 的二叉樹最多有 2^k - 1 個結(jié)點 (k>=1). (3) 對任何一棵二叉樹,如果其葉子結(jié)點數(shù)為 n0, 度為 2 的結(jié)點數(shù)為 n2,...

    FrancisSoung 評論0 收藏0
  • JS之數(shù)據(jù)結(jié)構(gòu)與算法 (5)

    摘要:序列文章面試之函數(shù)面試之對象面試之數(shù)組的幾個不操作面試之對比分析前言數(shù)據(jù)結(jié)構(gòu)是計算機存儲組織數(shù)據(jù)的方式算法是系統(tǒng)描述解決問題的策略。了解基本的數(shù)據(jù)結(jié)構(gòu)和算法可以提高代碼的性能和質(zhì)量。 showImg(https://segmentfault.com/img/bVbqYZQ?w=3000&h=2250); 序列文章 JS面試之函數(shù)(1)JS面試之對象(2)JS面試之數(shù)組的幾個不low操作...

    wangtdgoodluck 評論0 收藏0
  • [Leetcode] Binary Tree Traversal 二叉樹遍歷

    摘要:棧迭代復(fù)雜度時間空間遞歸棧空間對于二叉樹思路用迭代法做深度優(yōu)先搜索的技巧就是使用一個顯式聲明的存儲遍歷到節(jié)點,替代遞歸中的進程棧,實際上空間復(fù)雜度還是一樣的。對于先序遍歷,我們出棧頂節(jié)點,記錄它的值,然后將它的左右子節(jié)點入棧,以此類推。 Binary Tree Preorder Traversal Given a binary tree, return the preorder tr...

    RaoMeng 評論0 收藏0
  • 樹和樹的算法

    摘要:樹和樹的算法一樹樹的概念樹英語是一種抽象數(shù)據(jù)類型或是實作這種抽象數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),用來模擬具有樹狀結(jié)構(gòu)性質(zhì)的數(shù)據(jù)集合。一種時間復(fù)雜度額外空間復(fù)雜度的二叉樹的遍歷方式,為二叉樹的節(jié)點個數(shù)。 樹和樹的算法 一、樹 1.1 樹的概念 樹(英語:tree)是一種抽象數(shù)據(jù)類型(ADT)或是實作這種抽象數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),用來模擬具有樹狀結(jié)構(gòu)性質(zhì)的數(shù)據(jù)集合。它是由n(n>=1)個有限節(jié)點組成一個...

    RaoMeng 評論0 收藏0
  • 樹和樹的算法

    摘要:樹和樹的算法一樹樹的概念樹英語是一種抽象數(shù)據(jù)類型或是實作這種抽象數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),用來模擬具有樹狀結(jié)構(gòu)性質(zhì)的數(shù)據(jù)集合。一種時間復(fù)雜度額外空間復(fù)雜度的二叉樹的遍歷方式,為二叉樹的節(jié)點個數(shù)。 樹和樹的算法 一、樹 1.1 樹的概念 樹(英語:tree)是一種抽象數(shù)據(jù)類型(ADT)或是實作這種抽象數(shù)據(jù)類型的數(shù)據(jù)結(jié)構(gòu),用來模擬具有樹狀結(jié)構(gòu)性質(zhì)的數(shù)據(jù)集合。它是由n(n>=1)個有限節(jié)點組成一個...

    PiscesYE 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<