用JavaScript來實現鏈表LinkedList

来源:http://www.cnblogs.com/tdws/archive/2016/11/05/6033209.html
-Advertisement-
Play Games

本文版權歸博客園和作者本人共同所有,轉載和爬蟲請註明原文地址。 寫在前面 好多做web開發的朋友,在學習數據結構和演算法時可能比較討厭C和C++,上學的時候寫過的也忘得差不多了,更別提沒寫過的了。但幸運的是,你會JavaScript啊。我想說學好數據結構和基本演算法並非是要我們必須要去書寫,演算法的工作有 ...


本文版權歸博客園和作者本人共同所有,轉載和爬蟲請註明原文地址。

寫在前面

好多做web開發的朋友,在學習數據結構和演算法時可能比較討厭C和C++,上學的時候寫過的也忘得差不多了,更別提沒寫過的了。但幸運的是,你會JavaScript啊。我想說學好數據結構和基本演算法並非是要我們必須要去書寫,演算法的工作有專業的職位專業的人來做,但是如果你希望走的更高,這些是必不可少的,比如你學習Redis,如果hashmap等相關結構的話,也只能停留在使用的層次上,永遠和優化不能掛鉤。我也是個一瓶子不滿半瓶子晃悠,和希望快速成長的伙伴們共同加深印象,共同提高吧。

如果你對JavaScript OOP還不太瞭解的話,請移步這兩篇分享:http://www.cnblogs.com/tdws/p/5947693.html    http://www.cnblogs.com/tdws/p/5944254.html

如果你希望學習redis的話,可以看下這個鏈接 http://www.cnblogs.com/tdws/tag/NoSql/

 

進入正題

鏈表是一種動態的數據結構,不同於數組的是,鏈表分配記憶體空間的靈活性,它不會像數組一樣被分配一塊連續的記憶體。當你想在數組的任意位置,插入一個新值的時候,必須對數組中的各個元素進行相應的位置移動才能達到目標,開銷顯然是很大的。然而鏈表的靈活性在於它的每個元素節點分為兩部分,一部分是存儲元素本身,另一部分是指向下一個節點元素的引用,也可以稱為指針,當你要插入數據時,把上一個節點的向下指針指向新數據節點,新數據節點的向下指針指向原有數據。但是鏈表不像數組那樣可以直接通過索引立刻定位,只能通過遍歷。

圖畫的可能是亂了點,就是想突出一下,鏈表分配記憶體的動態性,你隨時隨地,都可以增加和刪除,並且記憶體的不連續性和無索引性。我暫時給鏈表類定義如下幾個方法

一個append追加元素,一個removeAt移除指定位置元素,一個insert在指定位置插入元素,toString輸出元素,一個indexOf尋找指定元素的索引。先上代碼吧:

    function LinkedList() {
        var Node = function (element) {        //新元素構造
            this.element = element;
            this.next = null;
        };
        var length = 0;
        var head = null;

        this.append = function (element) {
            var node = new Node(element);        //構造新的元素節點
            var current;
            if (head === null) {             //頭節點為空時  當前結點作為頭節點
                head = node;
            } else {
                current = head;              
                while (current.next) {          //遍歷,直到節點的next為null時停止迴圈,當前節點為尾節點
                    current = current.next;
                }
                current.next = node;            //將尾節點指向新的元素,新元素作為尾節點
            }           
            length++;                    //更新鏈表長度
        };
        this.removeAt = function (position) {
            if (position > -1 && position < length) {
                var current = head;
                var index = 0;
                var previous;
                if (position == 0) {
                    head = current.next;
                } else {
                    while (index++ < position) {
                        previous = current;
                        current = current.next;
                    }
                    previous.next = current.next;
                }
                length--;
                return current.element;
            } else {
                return null;
            }
        };
        this.insert = function (position, element) {
            if (position > -1 && position <= length) {        //校驗邊界
                var node = new Node(element);        
                current = head;
                var index = 0;
                var previous;
                if (position == 0) {                    //作為頭節點,將新節點的next指向原有的頭節點。
                    node.next = current;
                    head = node;                        //新節點賦值給頭節點
                } else {
                    while (index++ < position) {
                        previous = current;
                        current = current.next;
                    }                                //遍歷結束得到當前position所在的current節點,和上一個節點
                    previous.next = node;                    //上一個節點的next指向新節點  新節點指向當前結點,可以參照上圖來看
                    node.next = current;
                }
                length++;
                return true;
            } else {
                return false;
            }

        };
        this.toString = function () {
            var current = head;
            var string = '';
            while (current) {
                string += ',' + current.element;
                current = current.next;
            }
            return string;
        };
        this.indexOf = function (element) {
            var current = head;
            var index = -1;
            while (current) {
                if (element === current.element) {            //從頭節點開始遍歷
                    return index;
                }
                index++;
                current = current.next;
            }
            return -1;
        };
        this.getLength = function () {
            return length;
        }

    }
寫在最後

接下來將將分享雙向LinkedList和hashMap以便談及redis數據類型以及一些基本演算法。

如果我的點滴分享對您有點滴幫助。歡迎你為自己點贊,也為我點贊。也歡迎點擊紅色按鈕長期關註,我將持續分享。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 秋招結束了~~,好像偷懶了很久,沒更博了。總結一下自己近來看書的內容。 說明一下,內容大部分來自《高性能網站建設進階指南》。 亂入內容 Web應用和傳統桌面應用有一個共同的目標:儘可能快地響應用戶輸入。 怎樣才算是快?Jakob Nielsen是Web可用性領域知名且備受推崇的專家,引用他的觀點來說 ...
  • 前言 隨著頁面的內容豐富,以及網站體驗更好、性能優化等,原有的通過script標簽引入JavaScript腳本的方式已經不能很好地解決,此時新的一種JavaScript載入方式產生了——延時載入、執行。而js(JavaScript,下同)模塊化可以說是上面延時、執行的一種表示形式。 requirej ...
  • 今天(周六)下午我在公司加班時不知道要乾什麼,就打開公司的一個wordpress項目網站,想看下之前自己做的一個網頁是否有問題。 打開網站首頁,我習慣性的打開了chrome的調試工具,然後滑鼠開始滾動頁面,然後問題就出來了:頁面無法向下滾動,調試工具的console里報了好多undefined的錯誤 ...
  • 一、事件: 1、模式觸發事件: ①DOM:elem.onXXX();只能觸發直接用onXXX綁定的事件處理函數;用addEventistener添加的事件監聽無法模擬出發觸發; ②jQuery:$(...).trigger("事件名");可簡寫:$(...).事件名; 2、頁面載入後執行: ①jQu ...
  • 寫的比較弱,只能處理50道以內的選項為A-D的單選題,正確答案自己輸進去,必須要大寫,不能有空格和逗號,提交會出分,錯誤的題號和答案會console.log()出來. <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></ti ...
  • 這是我在面試大公司時碰到的一個筆試題,當時自己雲里霧裡的胡寫了一番,回頭也曾思考過,最終沒實現也就不了了之了。 昨天看到有網友說面試中也碰到過這個問題,我就重新思考了這個問題的實現方法。 對於想進大公司的童鞋,我想多說兩句,基礎知識真的很關鍵。平時在工作中也深刻體會到,沒有扎實的基礎知識,簡單問題容 ...
  • 目前來看,團隊內部前端項目已全面實施組件化開發。組件化的好處太多,如:按需載入、可復用、易維護、可擴展、少挖坑、不改組件代碼直接切成伺服器端渲染(如 "Nuclear" 組件化可以做到,大家叫同構)... 怎麼做到這麼強大的優勢,來回憶下以前見過的坑,或者現有項目里的坑。 CSS層疊樣式?保佑不要污 ...
  • 1. 使用require.js的意義 (1)實現JS文件的非同步載入,避免網頁因為載入JS文件緩慢造成網頁未響應 (2)管理模塊之間的依賴性,便於代碼的編寫和維護。頁面中只需要引入require.js和main.js,其餘的js文件全部通過require.js管理。 2. 獲取require.js r ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...