@@ -1191,6 +1191,160 @@ MyLinkedList.prototype.deleteAtIndex = function(index) {
11911191 */
11921192```
11931193
1194+ ``` js
1195+ /**
1196+ 定义双头节点的结构:同时包含前指针`prev`和后指针next`
1197+ */
1198+ class Node {
1199+ constructor (val , prev , next ) {
1200+ this .val = val
1201+ this .prev = prev
1202+ this .next = next
1203+ }
1204+ }
1205+
1206+ /**
1207+ 双链表:维护 `head` 和 `tail` 两个哨兵节点,这样可以简化对于中间节点的操作
1208+ 并且维护 `size`,使得能够以O(1)时间判断操作是否合法
1209+ */
1210+ var MyLinkedList = function () {
1211+ this .tail = new Node (- 1 )
1212+ this .head = new Node (- 1 )
1213+ this .tail .prev = this .head
1214+ this .head .next = this .tail
1215+ this .size = 0
1216+ };
1217+
1218+ /**
1219+ * 获取在index处节点的值
1220+ *
1221+ * @param {number} index
1222+ * @return {number}
1223+ *
1224+ * 时间复杂度: O(n)
1225+ * 空间复杂度: O(1)
1226+ */
1227+ MyLinkedList .prototype .get = function (index ) {
1228+ // 当索引超出范围时,返回-1
1229+ if (index > this .size ) {
1230+ return - 1
1231+ }
1232+
1233+ let cur = this .head
1234+ for (let i = 0 ; i <= index; i++ ) {
1235+ cur = cur .next
1236+ }
1237+
1238+ return cur .val
1239+ };
1240+
1241+ /**
1242+ * 在链表头部添加一个新节点
1243+ *
1244+ * @param {number} val
1245+ * @return {void}
1246+ *
1247+ * 时间复杂度: O(1)
1248+ * 空间复杂度: O(1)
1249+ */
1250+ MyLinkedList .prototype .addAtHead = function (val ) {
1251+ /**
1252+ head <-> [newNode] <-> originNode
1253+ */
1254+ this .size ++
1255+ const originNode = this .head .next
1256+ // 创建新节点,并建立连接
1257+ const newNode = new Node (val, this .head , originNode)
1258+
1259+ // 取消原前后结点的连接
1260+ this .head .next = newNode
1261+ originNode .prev = newNode
1262+ };
1263+
1264+ /**
1265+ * 在链表尾部添加一个新节点
1266+ *
1267+ * @param {number} val
1268+ * @return {void}
1269+ *
1270+ * 时间复杂度: O(1)
1271+ * 空间复杂度: O(1)
1272+ */
1273+ MyLinkedList .prototype .addAtTail = function (val ) {
1274+ /**
1275+ originNode <-> [newNode] <-> tail
1276+ */
1277+ this .size ++
1278+ const originNode = this .tail .prev
1279+
1280+ // 创建新节点,并建立连接
1281+ const newNode = new Node (val, originNode, this .tail )
1282+
1283+ // 取消原前后结点的连接
1284+ this .tail .prev = newNode
1285+ originNode .next = newNode
1286+ };
1287+
1288+ /**
1289+ * 在指定索引位置前添加一个新节点
1290+ *
1291+ * @param {number} index
1292+ * @param {number} val
1293+ * @return {void}
1294+ *
1295+ * 时间复杂度: O(n)
1296+ * 空间复杂度: O(1)
1297+ */
1298+ MyLinkedList .prototype .addAtIndex = function (index , val ) {
1299+ // 当索引超出范围时,直接返回
1300+ if (index > this .size ) {
1301+ return
1302+ }
1303+ this .size ++
1304+
1305+ let cur = this .head
1306+ for (let i = 0 ; i < index; i++ ) {
1307+ cur = cur .next
1308+ }
1309+
1310+ const new_next = cur .next
1311+
1312+ // 创建新节点,并建立连接
1313+ const node = new Node (val, cur, new_next)
1314+
1315+ // 取消原前后结点的连接
1316+ cur .next = node
1317+ new_next .prev = node
1318+ };
1319+
1320+ /**
1321+ * 删除指定索引位置的节点
1322+ *
1323+ * @param {number} index
1324+ * @return {void}
1325+ *
1326+ * 时间复杂度: O(n)
1327+ * 空间复杂度: O(1)
1328+ */
1329+ MyLinkedList .prototype .deleteAtIndex = function (index ) {
1330+ // 当索引超出范围时,直接返回
1331+ if (index >= this .size ) {
1332+ return
1333+ }
1334+
1335+ this .size --
1336+ let cur = this .head
1337+ for (let i = 0 ; i < index; i++ ) {
1338+ cur = cur .next
1339+ }
1340+
1341+ const new_next = cur .next .next
1342+ // 取消原前后结点的连接
1343+ new_next .prev = cur
1344+ cur .next = new_next
1345+ };
1346+ ```
1347+
11941348### TypeScript:
11951349
11961350``` TypeScript
0 commit comments