[go: up one dir, main page]

Menu

[r377]: / idl_lib / linked_list.pro  Maximize  Restore  History

Download this file

206 lines (184 with data), 5.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
;the definitive IDL linked list object
pro list_element__define
struct={list_element, next:ptr_new(), data:ptr_new()}
end
pro linked_list__define
struct={linked_list, $
head_ptr:ptr_new(), $
tail_ptr:ptr_new(), $
current_ptr:ptr_new(), $
current_el:0L, $
n:0L }
end
function linked_list::init, data
self.head_ptr=ptr_new({list_element})
self.tail_ptr=self.head_ptr
self.current_ptr=self.head_ptr
for i=0L, n_elements(data)-1 do begin
n=self->add(data[i])
; print, n
endfor
return, 1
end
pro linked_list::cleanup
self->reset
for i=0L, self.n-2 do begin
junk=self->delete_next()
endfor
ptr_free, (*self.head_ptr).data
ptr_free, self.head_ptr
ptr_free, self.tail_ptr
; stop
end
;adds an element to the end of the list:
function linked_list::add, data
; for i=0, n_elements(data)-1 do begin
(*self.tail_ptr).data=ptr_new(data)
if not ptr_valid((*self.tail_ptr).data) then return, -1
(*self.tail_ptr).next=ptr_new({list_element})
if not ptr_valid((*self.tail_ptr).next) then return, -1
self.current_ptr=self.tail_ptr
self.current_el=self.n
self.tail_ptr=(*self.tail_ptr).next
self.n=self.n+1
; endfor
return, self.n-1
end
;gets the nth element, where n is a zero-based index
;starts from the current element, if the requested element is
;equal to or greater
function linked_list::get, n
if n lt 0 or n ge self.n then return, ptr_new()
if n ge self.current_el then begin
offset=self.current_el
endif else begin
self.current_ptr=self.head_ptr
offset=0
endelse
for i=offset, n-1 do begin
self.current_ptr=(*self.current_ptr).next
endfor
self.current_el=n
return, (*(*self.current_ptr).data)
end
;deletes the nth element, where n is a zero-based index
;returns the deleted element
;if there is an error, returns a null pointer
pro linked_list::delete, n, deleted
nn=n_elements(n)
; for i=0, nn-1 do begin
if n lt 0 or n ge self.n then return
if self.n eq 0 then return
if n eq 0 then begin
self.current_ptr=self.head_ptr
deleted=(*(*self.current_ptr).data)
self.head_ptr=(*self.head_ptr).next
ptr_free, (*self.current_ptr).data
ptr_free, self.current_ptr
self.current_ptr=self.head_ptr
self.n=self.n-1
endif else begin
if n gt self.current_el then begin
offset=self.current_el
endif else begin
self.current_ptr=self.head_ptr
offset=0
endelse
for i=offset, n-2 do begin
self.current_ptr=(*self.current_ptr).next
endfor
previous_ptr=self.current_ptr
self.current_ptr=(*self.current_ptr).next
self.current_el=n
deleted=(*(*self.current_ptr).data)
(*previous_ptr).next=(*self.current_ptr).next
ptr_free, (*self.current_ptr).data
ptr_free, self.current_ptr
self.current_ptr=(*previous_ptr).next
self.n=self.n-1
endelse
; endfor
end
;steps the current pointer n forward in the list:
function linked_list::step, n
if n_elements(n) eq 0 then n=1
n=min([n, self.n-self.current_el-1])
for i=1, n do begin
self.current_ptr=(*self.current_ptr).next
self.current_el=self.current_el+1
endfor
return, self.current_el
end
function linked_list::get_current
return, (*self.current_ptr.data)
end
pro linked_list::reset
self.current_ptr=self.head_ptr
self.current_el=0
end
;deletes the element one forward from the current:
function linked_list::delete_next
if self.current_el ge self.n-1 then return, ptr_new()
hold=(*self.current_ptr).next
deleted=(*(*hold).data)
(*self.current_ptr).next=(*(*self.current_ptr).next).next
ptr_free, (*hold).data
ptr_free, hold
self.n=self.n-1
return, deleted
end
;inserts data after the nth element
pro linked_list::insert, data, n
if n lt 0 then return
if n ge self.n then begin
(*self.tail_ptr).next=ptr_new({list_element})
(*self.tail_ptr).data=ptr_new(ptr_new())
for i=self.n, n-1 do begin
;use null pointer for missing data element:
self.tail_ptr=(*self.tail_ptr).next
(*self.tail_ptr).data=ptr_new(ptr_new())
(*self.tail_ptr).next=ptr_new({list_element})
endfor
self.current_ptr=self.tail_ptr
self.tail_ptr=(*self.tail_ptr).next
self.n=n+1
self.current_el=n
endif else begin
if n ge self.current_el then begin
offset=self.current_el
endif else begin
self.current_ptr=self.head_ptr
offset=0
endelse
for i=offset, n-1 do begin
self.current_ptr=(*self.current_ptr).next
endfor
self.current_el=n
endelse
splice=(*self.current_ptr).next
(*self.current_ptr).next=ptr_new({list_element})
(*(*self.current_ptr).next).next=splice
(*(*self.current_ptr).next).data=ptr_new(data)
self.n=self.n+1
end
;returns the linked list converted to an array
;note: assumes all the elements are of the same type
pro linked_list::decompose, data
if self.n le 0 then return
data=replicate((*(*self.head_ptr).data), self.n)
current_ptr=self.head_ptr
for i=0, self.n-1 do begin
data[i]=(*(*current_ptr).data)
current_ptr=(*current_ptr).next
endfor
end
function linked_list::sizeof
return, self.n
end
pro linked_list::print
self->reset
for i=0, self.n-1 do begin
print, (*(*self.current_ptr).data)
n=self->step()
endfor
end