摘要:簡介本篇文章主要探討中的數(shù)據(jù)操作一直以來給人一種比較低能的感覺例如無法讀取系統(tǒng)上的文件不能做一些底層的操作所以在頁面上操作數(shù)據(jù)會交由服務(wù)器處理也就成了主流的做法但是很多人沒有發(fā)現(xiàn)實(shí)際上以及在逐步增強(qiáng)這些功能現(xiàn)在我們就已經(jīng)可以放心的在端進(jìn)行文
簡介
本篇文章主要探討JavaScript中的數(shù)據(jù)操作.
JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統(tǒng)上的文件,不能做一些底層的操作.
所以在頁面上操作數(shù)據(jù)會交由服務(wù)器處理也就成了主流的做法.
但是很多人沒有發(fā)現(xiàn),實(shí)際上JavaScript以及在逐步增強(qiáng)這些功能,現(xiàn)在我們就已經(jīng)可以放心的在web端進(jìn)行文件操作了.
起因N個(gè)月前我去新浪面試實(shí)習(xí),我提到了原來我做過一個(gè)頁面配合上傳Excel可以完成一些功能.
我的這番話勾起了面試官在實(shí)際編碼中遇到了一些問題,就是如何不通過服務(wù)器來操作數(shù)據(jù),我和她討論了一番,最后不了了之了(當(dāng)然也沒過).
N個(gè)月后實(shí)習(xí)被坑,成了無業(yè)游民閑來無事正好也好奇這個(gè)問題然后就研究了一下.
涉及的內(nèi)容沒有非必要的內(nèi)容,對于文件操作來說以下API都是必須了解的,本文也會漸進(jìn)式的討論這些內(nèi)容.
Blob
ArrayBuffer
TypedArray
DataView
FileReader
File
URL
兼容性我沒有詳細(xì)考證API的兼容性,不過從MDN提供的數(shù)據(jù)來看IE10以上的瀏覽器大部分都是兼容的.
總覽一般來說操作一個(gè)文件都要經(jīng)歷如下的步驟:
知道文件的地址(存放的位置)
讀取
保存到Buffer中,重復(fù)上步驟直至結(jié)束
進(jìn)行數(shù)據(jù)編輯
知道要寫入的地址
獲取要寫入的數(shù)據(jù),從Buffer中獲取還是所有數(shù)據(jù)
寫入
寫入完成
API名稱以及對應(yīng)的職責(zé):
名稱 | 職責(zé) |
---|---|
URL | 制造文件地址 |
FileReader | 讀取文件的接口 |
Blob | 用于在JavaScript表示文件 |
File | 用于表示文件對象 |
ArrayBuffer | 表示Buffer(僅僅提供一片內(nèi)存空間) |
TypedArray | 基于數(shù)組操作Buffer上的數(shù)據(jù)(操作的最小單位是數(shù)組元素) |
DataView | 基于字節(jié)操作Buffer上的數(shù)據(jù) |
上面描述的內(nèi)容之間的關(guān)系很復(fù)雜,這里我們逐步來進(jìn)行分析.
ArrayBufferhttps://developer.mozilla.org...
ArrayBuffer對象用于表示一段緩沖區(qū)域(可以理解為一段可控的內(nèi)存區(qū)域),它僅僅表示這片被開辟的區(qū)域但是不提供操作方式.
const arraybuffer = new ArrayBuffer(8) // 創(chuàng)建一個(gè)長度為8字節(jié)大小的Buffer
默認(rèn)ArrayBuffer中每一個(gè)字節(jié)都被填充了0.
利用這個(gè)對象我們可以完成如下的操作:
獲取
該Buffer的大小(字節(jié))
該Buffer的副本(范圍)
修改
該Buffer的大小
判斷
給定的數(shù)據(jù)是否是操作視圖(實(shí)例方法)
異常
當(dāng)創(chuàng)建的Buffer長度超過Number.MAX_SAFE_INTEGER的大小會產(chǎn)生錯(cuò)誤
const arraybuffer = new ArrayBuffer(8); console.log(arraybuffer.byteLength); // 獲取長度 console.log(arraybuffer.slice(4,8)); // 獲取副本 // 截止到2019年2月12日 20:11:05沒有瀏覽器實(shí)現(xiàn)該功能 console.log(arraybuffer.transfer(arraybuffer,16));// 修改原有Buffer console.log(ArrayBuffer.isView({})) // false 是否是視圖DataView
https://developer.mozilla.org...
DataView用于操作ArrayBuffer中的數(shù)據(jù),這也是它構(gòu)造函數(shù)中接受一個(gè)ArrayBuffer的原因:
const arraybuffer = new ArrayBuffer(8); const dataview = new DataView(arraybuffer); // 默認(rèn)的視圖大小就是buffer的大小 const offset = new DataView(arraybuffer, 0, arraybuffer.byteLength); // 默認(rèn)的偏移量以及長度
利用這個(gè)對象我們可以完成如下的操作:
獲取
被該視圖引入的Buffer(只讀)
該視圖從Buffer中讀取的自己長度(只讀)
該視圖從Buffer中讀取的偏移量(只讀)
異常
如果由偏移(byteOffset)和字節(jié)長度(byteLength)計(jì)算得到的結(jié)束位置超出了 buffer 的長度.
寫入
使用xxx類型寫入(見下方)
讀取
使用xxx類型讀取
可以使用的類型:
類型名稱 | 對應(yīng)的方法 |
---|---|
Int8 | getInt8,setInt8 |
Uint8 | getUint8,setUint8 |
Int16 | getInt16,setInt16 |
Uint16 | getUint16,setUint16 |
Int32 | getInt32,setInt32 |
Uint32 | getUint32,setUint32 |
Float32 | getFloat32,setFloat32 |
Float64 | getFloat64,setFloat64 |
簡單實(shí)例:
const arraybuffer = new ArrayBuffer(1); // 一個(gè)字節(jié) const dataview = new DataView(arraybuffer); // 默認(rèn)的視圖大小就是buffer的大小 dataview.setInt8(0,127) // 從0開始寫入一個(gè)int8(8位無符號整形,一個(gè)字節(jié)) dataview.getInt8(0) // 從偏移0開始讀取一個(gè)int8(8位無符號整形,一個(gè)字節(jié)) console.log(dataview.getInt8(0)); dataview.setInt16(0,65535); // 錯(cuò)誤超出了ArrayBuffer的空間 int16占兩個(gè)字節(jié)字節(jié)序
簡單來講-使用DataView:
在讀寫時(shí)不用考慮平臺字節(jié)序問題。
https://developer.mozilla.org...https://zh.wikipedia.org/wiki...
可以利用這個(gè)函數(shù)來進(jìn)行判斷:
var littleEndian = (function() { var buffer = new ArrayBuffer(2); new DataView(buffer).setInt16(0, 256, true /* 設(shè)置值時(shí)使用小端字節(jié)序 */); // Int16Array 使用系統(tǒng)字節(jié)序,由此可以判斷系統(tǒng)是否是小端字節(jié)序 return new Int16Array(buffer)[0] === 256; })(); console.log(littleEndian); // true or falseTypedArray
https://developer.mozilla.org...
在上面一節(jié)中我們使用get和set的方式基于數(shù)據(jù)類型來讀寫內(nèi)存(ArrayBuffer)中的數(shù)據(jù).
而所謂的TypedArray就是使用類似于操作數(shù)組的方式來操作我們的Buffer可以理解為數(shù)組中的每一個(gè)元素都是不同類型的數(shù)據(jù),這樣一來我們可以使用數(shù)組上的很多方法,相較于干巴巴的使用get和set更加靈活一些,少掉點(diǎn)頭發(fā).
名字叫做TypedArray的這個(gè)對象或者全局構(gòu)造函數(shù)并不存在于JavaScript中.因?yàn)轭愋蛿?shù)組并不只有一個(gè),但是TypedArray代指的這些內(nèi)容擁有統(tǒng)一的構(gòu)造函數(shù),統(tǒng)一的屬性統(tǒng)一的方法,不同的只是他們的名字以及所對應(yīng)的數(shù)據(jù)類型.
TypedArray()指的是以下的其中之一: Int8Array(); Uint8Array(); Uint8ClampedArray(); Int16Array(); Uint16Array(); Int32Array(); Uint32Array(); Float32Array(); Float64Array();
看到這里我們立馬聯(lián)想到了之前DataView上不同的Get和Set,概念是一樣的,不同于ArrayBuffer的是,這里的最小數(shù)據(jù)單位是數(shù)組中的元素,不同類型元素所占用的空間是不同的,但是我們不需要考慮在字節(jié)層面上進(jìn)行控制.
接下來我們利用Int8Array來進(jìn)行討論:
構(gòu)造函數(shù)
傳入一個(gè)數(shù)值來表示類型數(shù)組中元素的數(shù)量
傳入任意一個(gè)類型數(shù)組在保留其原有的長度上進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換
方法(靜態(tài))
Int8Array.from()通過可迭代對象創(chuàng)建一個(gè)類型數(shù)組
Int8Array.of()通過可變參數(shù)創(chuàng)建一個(gè)類型數(shù)組
例子:
// 32無符號能表示的最大的數(shù)值 占4個(gè)字節(jié) const int32 = new Int32Array(1); // 使用length int32[0] = 4294967295; // 8位無符號能表示最大的內(nèi)容是127 占1個(gè)字節(jié) const int8 = new Int8Array(int32); // 使用另外一個(gè)類型數(shù)組 console.log(int8[0]) // -1 32位轉(zhuǎn)8位要確保,32位的值在8位的范圍內(nèi)否則無法保證精度 const from = Int8Array.from([0,127]); console.log(from.length === 2) // true const of = Int8Array.of(0,127); console.log(of.length === 2)// true
屬性(靜態(tài))
TypedArray.BYTES_PER_ELEMENT
TypedArray.length
TypedArray.name
get TypedArray[@@species]
TypedArray.prototype
屬性(實(shí)例)
TypedArray.prototype.buffer
TypedArray.prototype.byteLength
TypedArray.prototype.byteOffset
TypedArray.prototype.length
方法(實(shí)例)
方法是在是太多了Array上的方法TypedArray基本都有,例舉太多都是照搬MDN,給個(gè)貼上大家自行查閱吧.
方法列表
例子(類數(shù)組操作):
const int8 = new Int8Array(2); int8[0] = 0; int8[1] = 127; int8.forEach((value)=>console.log(value)); for (const elem of int8) { console.log(elem); } Array.isArray(int8) // false 類數(shù)組而不是真的數(shù)組Blob
https://developer.mozilla.org...Blob` 對象表示一個(gè)不可變、原始數(shù)據(jù)的類文件對象。Blob 表示的不一定是JavaScript原生格式的數(shù)據(jù)
這說明了什么意思,類似于ArrayBuffer一樣,ArrayBuffer本身沒有為了達(dá)到某種目的而提供具體的操作方法,他的存在就類似于一個(gè)占位符一樣,Blob對象也是類似的概念,在JavaScript中我們使用Blob對象來表示一個(gè)文件,當(dāng)這個(gè)文件需要進(jìn)行操作的時(shí)候我們在利用其他途徑對這個(gè)Blob對象進(jìn)行操作.(個(gè)人理解)
Blob的API和ArrayBuffer非常相似,因?yàn)樗麄冇兄浅C芮械穆?lián)系,創(chuàng)建Blob對象有兩種方式,對應(yīng)著兩種具體的需求:
直接調(diào)用構(gòu)造函數(shù)傳入JavaScript中的數(shù)據(jù)結(jié)構(gòu)
使用File對象創(chuàng)建,用于表示文件
這里我們不討論由File對象創(chuàng)建的情況,這部分留到下節(jié)中討論.
構(gòu)造函數(shù)
你可以利用現(xiàn)有的JavaScript數(shù)據(jù)結(jié)構(gòu)來創(chuàng)建一個(gè)Blob對象
你可以選擇這個(gè)Blob對象的MIME類型
你可以控制這個(gè)Blob對象中的換行符在系統(tǒng)中表現(xiàn)的行為
具體參考
屬性(實(shí)例)
size - Blob對象所包含的數(shù)據(jù)大小
type - Blob對象所描述的MIME類型
方法(實(shí)例)
slice()類似于ArrayBuffer.slice()從原有的Blob中分離出一部分組成新的Blob對象
例子:
const blob1 = new Blob([JSON.stringify({ content: "success" })], { type: "application/json" }); const blob2 = new Blob(["hey!"],{ type:"text/html" });
注意:Blob對象接受的第一個(gè)參數(shù)是一個(gè)數(shù)組.
Blob對象還可以根據(jù)其他數(shù)據(jù)結(jié)構(gòu)進(jìn)行創(chuàng)建:
ArrayBuffer
ArrayBufferView(TypedArray)
Blob
https://developer.mozilla.org...
乍一看Blob對象看似很雞肋,不過在JavaScript中能裝載數(shù)據(jù)還可以指定MIME類型,這種情況多半都是用于和外部進(jìn)行交互.
回顧前面的內(nèi)容,我們知道了如何創(chuàng)建一片內(nèi)存中的區(qū)域,還知道了如何利用不同的工具來對這篇內(nèi)存進(jìn)行操作,最重要的一個(gè)用于描述文件Blob對象接受ArrayBuffer和TypedArray,那么還能玩出什么花樣呢?
File文件(File)接口提供有關(guān)文件的信息,并允許網(wǎng)頁中的 JavaScript 訪問其內(nèi)容。https://developer.mozilla.org...
File對象用于描述文件,這個(gè)對象雖然可以利用構(gòu)造函數(shù)自行創(chuàng)建,但是大多數(shù)情況下都是利用瀏覽器上的元素或者拖拽API來獲取的.
File對象繼承Blob對象,所以繼承了Blob對象上的原型方法和屬性,和Blob純粹表示文件不同,File更加接地氣一點(diǎn),他還擁有了我們操作系統(tǒng)上常見的一些特征:
屬性(實(shí)例)
lastModified 最后修改時(shí)間
name 文件名稱
size 文件大小
type MIME類型
詳細(xì)介紹
構(gòu)造函數(shù)
詳細(xì)介紹
例子:
// 創(chuàng)建buffer const buffer = new Int8Array(2); console.log(buffer.byteLength); // 2 buffer[0] = 0; buffer[1] = 127 console.log(buffer[0]); // 127 // 利用buffer創(chuàng)建一個(gè)file對象 const file = new File([buffer],"text.txt",{ type:"text/plain", lastModified:Date.now() }); // file繼承blob所以可以使用slice方法,返回一個(gè)blob對象 const blob = file.slice(1,2,"text/plain"); console.log(blob.size); //1
File對象目前看來依然扮演者"載體"的角色,不過在將他交由其他的API的時(shí)候才是他真正發(fā)揮威力的地方.
FileReaderFileReader一看名字我就有一種想喊JavaScript(瀏覽器端)永不為奴的沖動.前面鋪墊了那么多終于可以看到真正可以實(shí)際利用的內(nèi)容了.
FileReader 對象允許Web應(yīng)用程序異步讀取存儲在用戶計(jì)算機(jī)上的文件(或原始數(shù)據(jù)緩沖區(qū))的內(nèi)容,使用 File 或 Blob 對象指定要讀取的文件或數(shù)據(jù)。https://developer.mozilla.org...
FileReader和前面的所提到的內(nèi)容不同的地方在于,這個(gè)API有事件,你可以使用onXXX和addEventListener進(jìn)行監(jiān)聽.
基本工作流程:
獲取用戶提供的文件對象(通過input或者拖拽)
或者自己創(chuàng)建File或者(Blob)對象
新建一個(gè)FileReader()實(shí)例
監(jiān)聽對應(yīng)的方法來獲取讀取內(nèi)容完成后的回調(diào)
利用不同的方法讀取文件內(nèi)容
讀取為fileReader.ArrayBuffer()
讀取為DataURLfileReader.readAsDataURL()
讀取為字符串fileReader.readAsText()
示例1讀取計(jì)算機(jī)上的文件:
blob
如果一切順利,你就可以從計(jì)算機(jī)上讀取一個(gè)文件,并且以文本的形式展現(xiàn)在了控制臺中.
而且不僅如此,利用:
reader.readAsArrayBuffer(file)
我們可以讀取任何類型的數(shù)據(jù),然后再內(nèi)存中進(jìn)行修改,剩下的就差保存了.
FileReaderSync這個(gè)API是FileReader的同步版本,這意味著代碼執(zhí)行到讀取的時(shí)候會等待文件的讀取,所以這個(gè)API只能在workers里面使用,如果在主線程中調(diào)用它會阻塞用戶界面的執(zhí)行.
由于是同步讀取,所以沒有回調(diào)掉必要存在,也就不需要監(jiān)聽事件了.
https://developer.mozilla.org...URL
前面我們討論完成了數(shù)據(jù)的讀取,在FileReader中我們已經(jīng)可以獲取ArrayBuffer然后使用DateView和TypedArray就可以修改ArrayBuffer完成文件的修改,接下來我們旅行中的最后一程.
https://developer.mozilla.org...
在JavaScript(瀏覽器端)中我們可以使用URL來創(chuàng)建一個(gè)URL對象:
new URL("https://www.xxx.com?q=10")
他返回的對象包含如下的內(nèi)容:
// 控制臺 new URL("https://www.xxx.com?q=10") URL hash: "" host: "www.xxx.com" hostname: "www.xxx.com" href: "https://www.xxx.com/?q=10" origin: "https://www.xxx.com" password: "" pathname: "/" port: "" protocol: "https:" search: "?q=10" searchParams: URLSearchParams { } username: ""
可見該對象是一個(gè)工具對象用于幫助我們更加容易的處理URL.
例子(來自MDN):
var a = new URL("/", "https://developer.mozilla.org"); // Creates a URL pointing to "https://developer.mozilla.org/" var b = new URL("https://developer.mozilla.org"); // Creates a URL pointing to "https://developer.mozilla.org" var c = new URL("en-US/docs", b); // Creates a URL pointing to "https://developer.mozilla.org/en-US/docs" var d = new URL("/en-US/docs", b); // Creates a URL pointing to "https://developer.mozilla.org/en-US/docs" var f = new URL("/en-US/docs", d); // Creates a URL pointing to "https://developer.mozilla.org/en-US/docs" var g = new URL("/en-US/docs", "https://developer.mozilla.org/fr-FR/toto"); // Creates a URL pointing to "https://developer.mozilla.org/en-US/docs" var h = new URL("/en-US/docs", a); // Creates a URL pointing to "https://developer.mozilla.org/en-US/docs" var i = new URL("/en-US/docs", ""); // Raises a SYNTAX ERROR exception as "/en-US/docs" is not valid var j = new URL("/en-US/docs"); // Raises a SYNTAX ERROR exception as "about:blank/en-US/docs" is not valid var k = new URL("http://www.example.com", "https://developers.mozilla.com"); // Creates a URL pointing to "https://www.example.com" var l = new URL("http://www.example.com", b); // Creates a URL pointing to "https://www.example.com"
實(shí)際上這和Node中的URL對象十分相似:
// 終端 > Node > new URL("https://www.xxx.com/?q=10") URL { href: "https://www.xxx.com/?q=10", origin: "https://www.xxx.com", protocol: "https:", username: "", password: "", host: "www.xxx.com", hostname: "www.xxx.com", port: "", pathname: "/", search: "?q=10", searchParams: URLSearchParams { "q" => "10" }, hash: "" }
它和我們討論的文件下載有什么關(guān)系呢,在我們在瀏覽器中一切可以利用的資源都有唯一的標(biāo)識符那就是URL.
而我們自定義或者讀取的文件需要通過URL對象創(chuàng)建一個(gè)指向我們定義資源的鏈接.
那么URL對象上提供了兩個(gè)靜態(tài)方法:
URL.createObjectURL() 創(chuàng)建根據(jù)URL或者Blob創(chuàng)建一個(gè)URL
URL.revokeObjectURL() 銷毀之前已經(jīng)創(chuàng)建的URL實(shí)例
那么生成的這個(gè)URL,可以被用在任何使用URL的地方,在這個(gè)例子中我們讀取一個(gè)圖片,然后將它賦值給img標(biāo)簽的src屬性,這會在你的瀏覽器中打開一張圖片.
blob
我們的圖片被如下格式的URL所描述:
blob:http://127.0.0.1:5500/b285f19f-a4e2-48e7-b8c8-5eae11751593導(dǎo)出文件實(shí)踐
主要是利用瀏覽器在解析到MIME為application/octet-stream類型的內(nèi)容會彈出下載對話框的特性.
我們有如下對策:
創(chuàng)建一個(gè)File對象修改他的type為application/octet-stream
使用這個(gè)File利用URL.createObjectURL()創(chuàng)建一個(gè)URL
重定向到這個(gè)URL,讓瀏覽器自動彈出下載框
const buffer = new ArrayBuffer(1024), array = new Int8Array(buffer); array.fill(1); const blob = new Blob(array), file = new File([blob],"test.txt",{ lastModified:Date.now(), type:"application/octet-stream" }); saveAs(file,"test.txt") const url = window.URL.createObjectURL(file); window.location.href = url;
上面這種方式簡單粗,不過導(dǎo)出的文件你得修改文件名稱.
我們只需要稍稍利用利用a標(biāo)簽就可以優(yōu)雅的完成這項(xiàng)任務(wù):
const buffer = new ArrayBuffer(1024), array = new Int8Array(buffer); array.fill(1); const blob = new Blob(array), file = new File([blob],"test.txt",{ lastModified:Date.now(), type:"text/plain;charset=utf-8" }); const url = window.URL.createObjectURL(file), a = document.createElement("a"); a.href = url; a.download = file.name; // see https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/a#%E5%B1%9E%E6%80%A7 a.click();
大功告成,利用HTML5的API我們終于可以愉快的在WEB上操作數(shù)據(jù)啦!
MDN上幾篇不錯(cuò)的指引分別是:
在web應(yīng)用程序中操作文件指南
JavaScript 類數(shù)組對象
Base64的編碼與解碼
參考https://github.com/SheetJS/js...https://github.com/eligrey/Fi...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/101743.html
摘要:高度的控制是自底向上的。因此,要解決這兩個(gè)問題,就需要將高度的控制方向顛倒過來高度的控制是自頂向下的。元素的高度是通過自頂向下的方式確定的比如,元素的高度是根據(jù)自底向上的方式確定的。 從一個(gè)常見問題開始討論:如何用css將一個(gè)元素的高度設(shè)置為【瀏覽器內(nèi)容窗口高度】。 方案一:使元素高度占滿屏幕 在css中,vh是一個(gè)特殊的長度單位,100vh的值就是【瀏覽器內(nèi)容窗口高度】。因此heig...
摘要:簡介本篇文章主要探討中的數(shù)據(jù)操作一直以來給人一種比較低能的感覺例如無法讀取系統(tǒng)上的文件不能做一些底層的操作所以在頁面上操作數(shù)據(jù)會交由服務(wù)器處理也就成了主流的做法但是很多人沒有發(fā)現(xiàn)實(shí)際上以及在逐步增強(qiáng)這些功能現(xiàn)在我們就已經(jīng)可以放心的在端進(jìn)行文 簡介 本篇文章主要探討JavaScript中的數(shù)據(jù)操作. JavaScript一直以來給人一種比較低能的感覺,例如無法讀取系統(tǒng)上的文件,不能做一些...
摘要:在本文中,筆者主要想分享一下自底向上構(gòu)建知識圖譜的全過程,拋磚引玉,歡迎大家交流。隨著自動知識抽取與加工技術(shù)的不斷成熟,當(dāng)前的知識圖譜大多采用自底向上的方式構(gòu)建,如的和微軟的知識庫。 阿里妹導(dǎo)讀:知識圖譜的構(gòu)建技術(shù)主要有自頂向下和自底向上兩種。其中自頂向下構(gòu)建是指借助百科類網(wǎng)站等結(jié)構(gòu)化數(shù)據(jù)源,從高質(zhì)量數(shù)據(jù)中提取本體和模式信息,加入到知識庫里。而自底向上構(gòu)建,則是借助一定的技術(shù)手段,從...
摘要:上一篇中已經(jīng)介紹了幾個(gè)簡單的排序算法,這一篇文章我將繼續(xù)向大家介紹排序算法相關(guān)的內(nèi)容,本篇的會介紹希爾排序快速排序歸并排序以及分治算法的思想,希望通過本文章能夠加深大家對排序算法的理解。 上一篇中已經(jīng)介紹了幾個(gè)簡單的排序算法,這一篇文章我將繼續(xù)向大家介紹排序算法相關(guān)的內(nèi)容,本篇的會介紹希爾排序、快速排序、歸并排序以及分治算法的思想,希望通過本文章能夠加深大家對排序算法的理解。 希爾排序...
閱讀 1265·2021-09-27 13:35
閱讀 2563·2021-09-06 15:12
閱讀 3380·2019-08-30 15:55
閱讀 2829·2019-08-30 15:43
閱讀 432·2019-08-29 16:42
閱讀 3446·2019-08-29 15:39
閱讀 3062·2019-08-29 12:28
閱讀 1239·2019-08-29 11:11