1+ /*
2+ * 定义节点
3+ */
4+ function Node ( element ) {
5+ this . element = element ;
6+ this . next = null ;
7+ this . prev = null ;
8+ }
9+
10+ /*
11+ * 定义双向链表
12+ */
13+ module . exports = function DoubleLinkedList ( ) {
14+ // 定义属性
15+ this . head = null ;
16+ this . tail = null ;
17+ this . length = 0 ;
18+
19+ // 尾部添加元素
20+ DoubleLinkedList . prototype . append = function ( element ) {
21+ // 创建节点
22+ var newNode = new Node ( element ) ;
23+
24+ // 插入元素
25+ if ( this . head === null ) {
26+ this . head = newNode ;
27+ this . tail = newNode ;
28+ } else {
29+ this . tail . next = newNode ;
30+ newNode . prev = this . tail ;
31+ this . tail = newNode ;
32+ }
33+ // 最后更新长度
34+ this . length ++ ;
35+ }
36+
37+ // 在任意位置上插入数据
38+ DoubleLinkedList . prototype . insert = function ( position , element ) {
39+ // 判断越界的问题
40+ if ( position < 0 || position > this . length ) return false
41+
42+ // 创建节点
43+ var newNode = new Node ( element ) ;
44+
45+ if ( position === 0 ) {
46+ // 判断头结点是否为空
47+ if ( this . head === null ) {
48+ this . head = newNode ;
49+ this . tail = newNode ;
50+ } else {
51+ this . head . prev = newNode ;
52+ newNode . next = this . head ;
53+ this . head = newNode ;
54+ }
55+ } else if ( position === this . length ) {
56+ // 当前插入到链表最后
57+ // 思考: 这种情况是否需要判断链表为空的情况呢? 答案是不需要, 为什么?
58+ this . tail . next = newNode ;
59+ newNode . prev = this . tail ;
60+ this . tail = newNode ;
61+ } else {
62+ // 在中间插入数据
63+ var index = 0 ;
64+ var current = this . head ;
65+ var previous = null ;
66+
67+ while ( index ++ < position ) {
68+ previous = current ;
69+ current = current . next ;
70+ }
71+
72+ // 插入节点
73+ newNode . next = current ;
74+ current . prev = newNode ;
75+ previous . next = newNode ;
76+ newNode . prev = previous ;
77+ }
78+ // 更新长度
79+ this . length ++ ;
80+ return true ;
81+ }
82+
83+ // 根据位置删除对应的元素
84+ DoubleLinkedList . prototype . removeAt = function ( position ) {
85+ // 判断越界的问题
86+ if ( position < 0 || position >= this . length ) return null ;
87+ // 判断移除的位置
88+ var current = this . head ;
89+ if ( position === 0 ) {
90+ if ( this . length === 1 ) {
91+ this . head = null ;
92+ this . tail = null ;
93+ } else {
94+ this . head = this . head . next ;
95+ this . head . prev = null ;
96+ }
97+ } else if ( position === this . length - 1 ) {
98+ current = this . tail ;
99+ this . tail = this . tail . prev ;
100+ this . tail . next = null ;
101+ } else {
102+ var index = 0 ;
103+ var previous = null ;
104+ while ( index ++ < position ) {
105+ previous = current ;
106+ current = current . next ;
107+ }
108+ previous . next = current . next ;
109+ current . next . prev = previous ;
110+ }
111+ // 更新长度
112+ this . length -- ;
113+ return current . element ;
114+ }
115+
116+ // 根据元素获取在链表中的位置
117+ DoubleLinkedList . prototype . indexOf = function ( element ) {
118+ // 定义变量保存信息
119+ var current = this . head ;
120+ var index = 0 ;
121+ // 查找正确的信息
122+ while ( current ) {
123+ if ( current . element === element ) {
124+ return index ;
125+ }
126+ index ++ ;
127+ current = current . next ;
128+ }
129+ // 来到这个位置, 说明没有找到, 则返回-1
130+ return - 1 ;
131+ }
132+
133+ // 根据元素删除
134+ DoubleLinkedList . prototype . remove = function ( element ) {
135+ var index = this . indexOf ( element ) ;
136+ return this . removeAt ( index ) ;
137+ }
138+
139+ // 判断是否为空
140+ DoubleLinkedList . prototype . isEmpty = function ( ) {
141+ return this . length === 0 ;
142+ }
143+
144+ // 获取链表长度
145+ DoubleLinkedList . prototype . size = function ( ) {
146+ return this . length ;
147+ }
148+
149+ // 获取第一个元素
150+ DoubleLinkedList . prototype . getHead = function ( ) {
151+ return this . head . element ;
152+ }
153+
154+ // 获取最后一个元素
155+ DoubleLinkedList . prototype . getTail = function ( ) {
156+ return this . tail . element ;
157+ }
158+
159+ // 遍历方法的实现
160+ // 正向遍历的方法
161+ DoubleLinkedList . prototype . forwardString = function ( ) {
162+ var current = this . head ;
163+ var forwardStr = "" ;
164+ while ( current ) {
165+ forwardStr += ", " + current . element ;
166+ current = current . next ;
167+ }
168+ return forwardStr . slice ( 1 ) ;
169+ }
170+ // 反向遍历的方法
171+ DoubleLinkedList . prototype . reverseString = function ( ) {
172+ var current = this . tail ;
173+ var reverseStr = "" ;
174+ while ( current ) {
175+ reverseStr += ", " + current . element ;
176+ current = current . prev ;
177+ }
178+ return reverseStr . slice ( 1 ) ;
179+ }
180+
181+ // 实现toString方法
182+ DoubleLinkedList . prototype . toString = function ( ) {
183+ return this . forwardString ( ) ;
184+ }
185+ }
0 commit comments