Chapter 3
Linked Lists
Data Structure
Software College Northeastern University
Overview
Linked Lists
Programming details
Common Error
Doubly Linked Lists
Circularly Linked Lists
examples
Cursors Implementation of Linked Lists
Data Structure
Software College Northeastern University
Variable-length arrays?
Direct access to element (By indexing)
Array size is fixed-length
-To expand them, you create a new, longer array, and
copy the contents of the old array into the new array
This is used by function realloc() in C
This is slow!
Linear time Insertion/Removal due to shift elements
due to contiguous storage in memory
Half of the list needs to be moved for either
operations
Data Structure
Software College Northeastern University
Variable-length arrays?
Solution:
-The list is not need to store contiguously.
-Attach a pointer to each item in the array, which
points to the next item.
-provides the ability to add or remove the items
anywhere in the list in constant time
This is a linked list
Linked lists are unbounded
(maximum number of items limited only by memory)
Data Structure
Software College Northeastern University
The Linked List data structure
Array
Linked list
array
Head
[0] [1] [2]
A B C
node
A
B
C
An data item plus its pointer is called a node
A node contains data item and one or more links.
- The link is a reference to a node.
- The link of last node is set to NULL
a “head” which is a pointer to the first node in the
linked list
Data Structure
Software College Northeastern University
A simple single Linked List
Address
Header
H
31
H
1
7
13
19
25
31
37
43
Data Item
Links
LI
43
QIAN
SUN
13
1
WANG
WU
ZHAO
ZHENG
ZHOU
NULL
37
7
19
25
ZHAO
QIAN
SUN
LI
ZHOU
WU
ZHENG
WANG
Data Structure
Software College Northeastern University
^
Memory Storage of linked list
Heap
We can access all nodes through pointer “head”
Data Structure
Software College Northeastern University
Linked lists
Each node contains the address of the next one
in the list.
We can access the first node through pointer
“head”
two important pointer:
- head: the reference to the first node
- tail: the reference to the last node
Data Structure
Software College Northeastern University
How to implementate?
Data Structure
Software College Northeastern University
Definition of the class
Using multi class
Class of Node(ListNode)
Class of List
Class of Iterator
Type of Definition
compound
inside
Data Structure
Software College Northeastern University
class List;
class ListNode {
friend class List;
private:
int data;
ListNode *link;
};
List is a
Friend class
class List {
public:
………
private:
};
ListNode *first, *last;
Data Structure
Software College Northeastern University
class List {
public:
………
private:
class ListNode {
public:
int data;
ListNode *link;
};
ListNode *first, *last;
};
Data Structure
ListNode is a
class inside
List
Software College Northeastern University
Linked List:Inserting a new node(1)
int List::Insert ( const int x, const int i )
Insert a node with data equal to x after the i-1’th element.
(i.e., when i = 1, insert the node as the first element; when
index = 2, insert the node after the first element, and so
on)
If the insertion is successful, return 1.
Otherwise, return 0. (If index is < 1 or > length+1 of the
list, the insertion will fail.)
Steps
i’th element
1. Locate i-1’th element
2. Allocate memory for the new node
3. Point the new node to its successor
4. Point the new node’s predecessor to the new node
newNode
Data Structure
Software College Northeastern University
Linked List:Inserting a new node(2)
Insert position
Case 1:insert in front of the first node
newnode→link = first ;
first = newnode;
newnode
newnode
first
first
(Before)
Data Structure
(After)
Software College Northeastern University
Linked List:Inserting a new node(3)
Case
2:insert in the middle of the list
newnode→link = p→link;
p→link = newnode;
newnode
newnode
p
p
(Before)
Data Structure
(After)
Software College Northeastern University
Linked List:Inserting a new node(4)
Case 3:Insert in the rear
newnode→link = p→link;
p→link = last = newnode;
newnode
p
newnode
p
last
last
(Before)
Data Structure
(After)
Software College Northeastern University
From 0
Linked List:Inserting a new node(5)
int List::Insert ( const int x, const int i ) {
// Insert a node with data equal to x after the i-1’th
ListNode *p = first; int k = 0;
while ( p != NULL && k < i -1 )
{ p = p→link; k++; } // Locate i-1’th element
if ( i<0 || p == NULL && first != NULL ) {
cout << “无效的插入位置!\n”;
return 0;
}
ListNode *newnode= new ListNode(x, NULL);
// Allocate memory for the new node
Data Structure
Software College Northeastern University
Linked List:Inserting a new node(6)
if ( first == NULL || i == 0 ) {
//Insert in the front of list
newnode→link = first;
if ( first == NULL ) last = newnode;
first = newnode;
}
else {
//else
newnode→link = p→link;
if ( p→link == NULL ) last = newnode;
p→link = newnode;
}
return 1;
}Data Structure
Software College Northeastern University
Linked List:Inserting a new node
when we insert a new node:
(1)insert before the i’th element,
which pointer should we get first?
(2)illegal inserting position is ?
How can we judge inserting position is illegal?
(3)We should change two links when inserting ,
Is there an order?
Data Structure
Software College Northeastern University
Linked List:Deleting a new node(1)
Case 1: delete the first
Case 2: delete the other node
According the
pointer to i’th
element ,Can we
accomplish the
operation?
Delete the i’th element
Data Structure
Software College Northeastern University
Linked List:Deleting a new node(2)
int List::Remove ( int i ) {
//Delete the i’th element
Node *p = first, *q; int k = 0;
while ( p != NULL && k< i-1 )
{ p = p→link; k++; } //locate the i-1’th element
if (i<0 || p == NULL || p→link == NULL ) {
cout << “无效的删除位置!\n”;
return 0;
}
if ( i == 0 ) {
//delete the first
q = first;
//q point the deleted node
p = first = first→link;
//Update first
Data Structure
Software College Northeastern University
}
Linked List:Deleting a new node(3)
}
else {
q = p→link;
p→link = q→link;
}
if ( q == last ) last = p; //if necessary update last
k = q→data;
delete q;
//free the node pointed by q
return k;
Data Structure
Software College Northeastern University
Linked List with header
A node linking to the first node is called
Header, the header cell only contains
references to the first.
first
a1
an 0
first
last
Non-empty list
Data Structure
last
empty list
Software College Northeastern University
0
Inserting in a linked list with header
newnode→link = p→link;
if ( p→link == NULL ) last = newnode;
p→link = newnode;
Data Structure
Software College Northeastern University
Deleting in a linked list with header
q = p→link;
p→link = q→link;
delete q;
if ( p→link == NULL ) last = p;
Data Structure
Software College Northeastern University
Template of linked list(1)
template <class Type> class List;
template <class Type> class ListNode {
friend class List<Type>;
Type data;
//结点数据
ListNode<Type> *link;
//结点链接指针
public:
ListNode ( );
//链表结点构造函数
ListNode ( const Type& item );
ListNode<Type> *NextNode ( ) { return link; }
//给出当前结点的下一结点地址
Data Structure
Software College Northeastern University
Template of linked list(2)
void InsertAfter ( ListNode<Type> *p );
//在当前结点后插入结点p
ListNode<Type> *RemoveAfter ( );
//摘下当前结点的下一结点
};
template <class Type> class List {
ListNode<Type> *first, *last;
public:
ListNode<Type> *GetNode ( const Type&
item, ListNode<Type> *next );
//创建数据为item,指针为next的新结点
Data Structure
Software College Northeastern University
Template of linked list(3)
List ( const Type & value ) {
last =first = new ListNode<Type>( value );
}
//构造函数
~List ( );
//析构函数
void MakeEmpty ( );
//链表置空
int Length ( ) const;
//求链表长度
ListNode<Type> *Find ( Type value );
ListNode<Type> *Find ( int i );
int Insert ( Type value, int i );
Type *Remove ( int i );
Type *Get ( int i );
};Data Structure
Software College Northeastern University
Implementation of linked list(1)
template <class Type>
ListNode<Type> :: ListNode ( ) : link (NULL) { }
template <class Type>
ListNode<Type>::
ListNode( const Type& item ) :
data (item), link (NULL) { }
template <class Type>
void ListNode<Type>::
InsertAfter ( ListNode<Type> *p )
{ p→link = link; link = p; }
Data Structure
Software College Northeastern University
Implementation of linked list(2)
template <class Type> ListNode<Type>
*ListNode<Type>::RemoveAfter ( ) {
//摘下当前结点的下一结点
ListNode<Type> *tempptr = link;
if ( link == NULL ) return NULL;
//没有下一结点则返回空指针
link = tempptr→link;
//重新链接
return tempptr;
//返回下一结点地址
}
Data Structure
Software College Northeastern University
Implementation of linked list(3)
template <class Type>
ListNode<Type>*List<Type>::GetNode ( const Type
& item, ListNode<Type> *next = NULL ) {
ListNode<Type> *newnode =
new ListNode<Type> ( item );
newnode →link = next;
return newnode;
}
template <class Type> List<Type> :: ~List ( ){
//析构函数 (链表的公共操作)
MakeEmpty ( ); delete first;
//链表置空,再删去表头结点
Software College Northeastern University
} Data Structure
Implementation of linked list(4)
template <class Type>
void List<Type> :: MakeEmpty ( ) {
//删去链表中除表头结点外的所有其他结点
ListNode<Type> *q;
while ( first→link != NULL ) {
q = first→link; first→link = q→link;
//将表头结点后第一个结点从链中摘下
delete q;
//释放它
}
last = first;
//修改表尾指针
}
Data Structure
Software College Northeastern University
Implementation of linked list(5)
template <class Type>
int List<Type>::Length ( ) const {
//求单链表的长度
ListNode<Type> *p = first→link;
//检测指针p指示第一个结点
int count = 0;
while ( p != NULL ) {
//逐个结点检测
p = p→link; count++;
}
return count;
}
Data Structure
Software College Northeastern University
Implementation of linked list(6)
template <class Type>
ListNode<Type>*List <Type>::
Find ( Type value ) {
//在链表中从头搜索其数据值为value的结点
ListNode<Type> *p = first→link;
//检测指针 p 指示第一个结点
while ( p != NULL && p→data != value )
p = p→link;
return p;
// p 在搜索成功时返回找到的结点地址
// p 在搜索不成功时返回空值
} Structure
Data
Software College Northeastern University
Implementation of linked list(7)
template <class Type>
ListNode<Type> *List<Type> :: Find ( int i ) {
//在链表中从头搜索第 i 个结点,不计头结点
if ( i < -1 ) return NULL;
if ( i == -1 ) return first;
// i 应 0
ListNode<Type> *p = first→link;
int j = 0;
while ( p != NULL && j < i )
// j = i 停
{ p = p→link; j++; }
return p;
}
Data Structure
Software College Northeastern University
Implementation of linked list(7)
template <class Type>
int List<Type> :: Insert ( Type value, int i ) {
//将含value的新元素插入到链表第 i 个位置
ListNode<Type> *p = Find ( i-1 );
// p 指向链表第 i-1个结点
if ( p == NULL ) return 0;
ListNode<Type> *newnode = //创建结点
GetNode ( value, p→link );
if ( p→link == NULL ) last = newnode;
p→link = newnode;
//重新链接
return 1;
} Structure
Data
Software College Northeastern University
Implementation of linked list(8)
template <class Type>
Type *List<Type>::Remove ( int i ) {
//从链表中删去第 i 个结点
ListNode<Type> *p = Find (i-1), *q;
if ( p == NULL || p→link == NULL )
return NULL;
q = p→link; p→link = q→link;
//重新链接
Type value = new Type ( q→data );
if ( q == last ) last = p;
delete q;
return &value;
}
Data Structure
Software College Northeastern University
Implementation of linked list(8)
template <class Type>
Type *List<Type>::Get ( int i ) {
//提取第 i 个结点的数据
ListNode<Type> *p = Find ( i );
// p 指向链表第 i 个结点
if ( p == NULL || p == first )
return NULL;
else return & p→data;
}
Data Structure
Software College Northeastern University
Array versus Linked Lists
Linked lists are more complex to code and management than
arrays, but they have some distinct advantages.
Dynamic: a linked list can easily grow and shrink in size.
-We don’t need to know how many nodes will be in the list.
They are created in memory as needed.
-In contrast, the size of a C array is fixed at compilation
time.
Easy and fast insertions and deletions
-To insert or delete an element in an array, we need to
copy to temporary variables to make room for new
elements or close the gap caused by deleted elements.
-With a linked list, no need to move other nodes. Only
need to reset some pointers.
Data Structure
Software College Northeastern University
Arrays versus linked lists
Space (storage) considerations
A linked list requires pointers to nodes
An array requires the maximum number of
elements to be known in advance. If that
maximum is not required, space is wasted at
the end of the array.
Data Structure
Software College Northeastern University
Arrays versus linked lists
Time considerations
Most methods in a linked list require more
statements than those in an array, which may
indicate more time required
Arrays are quicker at finding and altering
‘in the middle’
Linked lists are quicker at additions and
removals ‘in the middle’
Data Structure
Software College Northeastern University
Iterator class of list
Iterator class of list is used to traverse
nodes of list.
priciple:
Iterator class is friend of List and ListNode
Iterator refer to the nodes of list。
Data member current point to the node
currently used
Iterator privides some test and find
operation
Data Structure
Software College Northeastern University
Template definition(1)
enum Boolean { False, True };
template <class Type> class List;
template <class Type> class ListIterator;
template <class Type> class ListNode { //表结点
friend class List <Type>;
friend class ListIterator <Type>;
public:
………
private:
Type data;
ListNode<Type> *link;
};
Data Structure
Software College Northeastern University
Template definition(2)
template <class Type> class List {
//链表类
public:
………
private:
ListNode<Type> *first, *last;
};
template <class Type> class ListIterator {
public:
ListIterator ( const List<Type> & l )
: list ( l ), current ( l.first->link ) { }
//构造函数: 引用链表 l, 表头为当前结点
private:
list<Type> list;
ListNode<Type> * current;
}
Data Structure
Software College Northeastern University
Template definition(3)
template <class Type>
Boolean ListIterator<Type> :: NotNull ( ) {
//检查链表中当前元素是否非空
if ( current != NULL ) return True;
else return False;
}
current
current
case 1 return True
Data Structure
case 2 return False
Software College Northeastern University
Template definition(4)
template <class Type>
Boolean ListIterator<Type>::NextNotNull ( ) {
//检查链表中下一元素是否非空
if ( current != NULL &&
current→link != NULL ) return True;
else return False;
}
current
current
case 1 return True
Data Structure
case 2 return False
Software College Northeastern University
Template definition(5)
template <class Type>
ListNode<Type>* ListIterator<Type> :: Firster ( ) {
//返回链表中头结点的地址
current = list.first;
return current;
}
list.first
Data Structure
current
list with header
Software College Northeastern University
Template definition(5)
template <class Type>
Type * ListIterator<Type> :: First ( ) {
//返回链表中第一个元素的地址
if ( list.first→link != NULL ){
current = list.first->link;
return ¤t→data;
}
else { current = NULL; return NULL; }
}
list.first
Data Structure
current
list with header
Software College Northeastern University
Template definition(6)
template <class Type>
Type* ListIterator<Type> :: Next ( ) {
//返回链表中当前结点的下一个结点的地址
if ( current != NULL
&& current→link != NULL ) {
current = current→link;
return & current→data;
}
else { current = NULL; return NULL; }
}
current
Data Structure
current
Software College Northeastern University
Calculating using iterator
int sum ( const List<int> &l ) {
ListIterator<int> li ( l );
//链表为空时返回0
int *p= li.First( ); retval = 0 //指向第一个结点
while ( p != null ){
//链表未扫描完
retval += *p;
//累加
p= li.Next( );
}
return retval;
} Data Structure
Software College Northeastern University
Variations of Linked Lists
Two problems
- we can’t get back to the beginning of the list
- from the end, and we can’t go backwards
through the list.
So, circular linked lists and doubly linked lists
were invented.
Data Structure
Software College Northeastern University
Variations of Linked Lists
Circular linked lists
The last node points to the first node of the
list
A
B
Head
How do we know when we have finished
traversing the list? (Tip: check if the pointer of
the current node is equal to the head.)
Data Structure
Software College Northeastern University
Implementation of Circular linked lists(1)
template <class Type> class CircList;
template <class Type> class CircListNode {
friend class CircList;
public:
CircListNode ( Type d = 0,
CircListNode<Type> *next = NULL ) :
data ( d ), link ( next ) { }
//构造函数
private:
Type data;
CircListNode<Type> *link;
}
Data Structure
Software College Northeastern University
Implementation of Circular linked lists(2)
template <class Type> class CircList {
public:
CircList ( Type value );
~CircList ( );
int Length ( ) const;
Boolean IsEmpty ( )
{ return first→link == first; }
Boolean Find ( const Type & value );
Type getData ( ) const;
void Firster ( ) { current = first; }
Boolean First ( );
Boolean Next ( );Software College Northeastern University
Data Structure
Implementation of Circular linked lists(3)
Boolean Prior ( );
void Insert ( const Type & value);
void Remove ( );
private:
CircListNode<Type> *first, *current, *last;
};
插入
Data Structure
Software College Northeastern University
Variations of Circular Linked Lists
Circular linked lists
construct an empty Circular linked list
List ( const Type & value ) {
last =first = new ListNode<Type>( value );
}
CircList ( const Type & value ) {
}
last =first = new CircListNode<Type>( value );
first->link = first;
Data Structure
Software College Northeastern University
Linked Lists: Searching in a CLL
template <class Type>
CircListNode<Type>*List <Type>::Find ( Type value ) {
//在链表中从头搜索其数据值为value的结点
CircListNode<Type> *p = first→link;
//检测指针 p 指示第一个结点
while ( p != first && p→data != value )
p = p→link;
return (p!=first)?p:NULL;
// p 在搜索成功时返回找到的结点地址
// p 在搜索不成功时返回空值
}
Data Structure
Software College Northeastern University
Variations of Linked Lists
Doubly linked lists
Each node points to not only successor but the
predecessor
There are two NULL: at the first and last nodes in
the list
Advantage: given a node, it is easy to visit its
predecessor. Convenient to traverse lists backwards
A
Head
Data Structure
Software College Northeastern University
B
Doubly linked lists
Non_empty list
empty list
p == p→lLink→rLink == p→rLink→lLink
Data Structure
Software College Northeastern University
Implementation of Doubly linked lists(1)
template <class Type> class DblList;
template <class Type> class DblNode {
friend class DblList<Type>;
private:
Type data;
//数据
DblNode<Type> *lLink, *rLink; //指针
DblNode ( Type value,
//构造函数
DblNode<Type> *left,
DblNode<Type> *right ) :
data (value), lLink (left), rLink (right) { }
Data Structure
Software College Northeastern University
Implementation of Doubly linked lists(2)
DblNode ( Type value ) : data (value),
lLink (NULL), rLink (NULL) { }
};
template <class Type> class DblList {
public:
DblList ( Type uniqueVal );
~DblList ( );
int Length ( ) const;
int IsEmpty ( ) { return first→rlink == first; }
int Find ( const Type & target );
Type getData ( ) const;
Data Structure
Software College Northeastern University
Implementation of Doubly linked lists(3)
void Firster ( ) { current = first; }
int First ( );
int Next ( );
int Prior ( );
int operator ! ( )
{ return current != NULL; }
void Insert ( const Type & value );
void Remove ( );
private:
DblNode<Type> *first, *current;
};
Data Structure
Software College Northeastern University
Doubly linked lists:Searching
Data Structure
Software College Northeastern University
Doubly Linked Lists:constructing
template <class Type>
DblList<Type>::DblLIst ( Type uniqueVal ) {
//双向循环链表的构造函数, 创建表头结点
first = new DblNode<Type> ( uniqueVal );
first→rLink = first→lLink = first;
current = NULL;
}
Data Structure
Software College Northeastern University
Doubly Linked Lists:searching
template <class Type> int DblList<Type>::
Find ( const Type & target ) {
//在双向循环链表中搜索含target的结点,
//搜索成功返回1,否则返回0。
DblNode<Type> *p = first→rLink;
while ( p != first && p→data != target )
p = p→rLink;
//循链搜索
if ( p != first ) { current = p; return 1; }
return 0;
}
Another method?
Data Structure
Software College Northeastern University
Doubly Linked Lists:Inserting(1)
1. p→lLink = current;
2. p→rLink =current→rLink;
3. current→rLink = p;
4. current = current→rLink;
5. current→rLink→lLink = current;
3
Data Structure
2
5
1
Software College Northeastern University
4
Doubly Linked Lists:Inserting(2)
template <class Type> void DblList<Type>::
Insert ( const Type & value ) {
if ( current == NULL )
//空表情形
current = first→rLink =
new DblNode ( value, first, first );
else {
//非空表情形
current→rLink =new DblNode
( value, current, current→rLink );
current = current→rLink;
}
current→rLink→lLink = current;
}
Data Structure
Software College Northeastern University
Doubly Linked Lists:Deleting(1)
1. current→rLink→lLink = current→lLink;
2. current→lLink→rLink = current→rLink;
2
Data Structure
1
Software College Northeastern University
Doubly Linked Lists:Deleting(2)
template <class Type>
void DblList<Type>::Remove ( ) {
if ( current != NULL ) {
DblNode *temp = current;
//被删结点
current = current→rLink;
//下一结点
current→lLink = temp→lLink; //从链中摘下
temp→lLink→rLink = current;
delete temp;
//删去
if ( current == first )
if ( IsEmpty ( ) ) current = NULL;
else current = current→rLink;
}
} Data Structure
Software College Northeastern University
Doubly Linked Lists:counting
template <class Type>
int DblList<Type>::Length ( ) const {
//求双向循环链表的长度(不计表头结点)
DblNode<Type> * p = first→rLink;
int count = 0;
while ( p != first )
{ p = p→rLink; count++; }
return count;
}
Data Structure
Software College Northeastern University
Doubly Linked Lists:Changing
template <class Type>
int DblList<Type>::First ( ) {
if ( !IsEmpty ( ) )
//跳过表头结点的第一个
{ current = first→rLink; return 1; }
current = NULL; return 0;
}
template <class Type>
int DblList<Type>::Next ( ) {
if ( current→rLink == first )
{ current = NULL; return 0; }
current = current→rLink; return 1;
}
Data Structure
Software College Northeastern University
Doubly Linked Lists:Changing
template <class Type>
int DblList<Type>::Prior ( ) {
if ( current→lLink == first )
{ current = NULL; return 0; }
current = current→lLink; return 1;
}
Data Structure
Software College Northeastern University
DLL compared to SLL
Advantages:
Disadvantages:
Can be traversed in
either direction (may
be essential for some
programs)
Requires more space
Some operations, such
as deletion and
inserting before a
node, become easier
Greater chance of
having bugs (because
more links must be
manipulated)
Data Structure
List manipulations are
slower (because more
links must be changed)
Software College Northeastern University
Linked Lists: Cursor Implementation
Problem:
Inserting or Deleting use new and delete to obtain and
release a piece of space
dynamic management
If operations of getting or returning are frequently, it
may indicate more time required
Two resolving way:
Cursor Implementation of linked lists using static
memory
Initially We allocate many nodes to linked into spare
lists
Data Structure
Software College Northeastern University
Linked Lists: Cursor Implementation
Tow important features of linked list:
The data are stored in a collection of structure,
each structure contains data and a pointer to
the next structure
A new structure can be obtained from the
system’s global memory by a call to new and
released by a call to delete
Implementation:
Have a global array of structure
Array index can be used in place of an address
Data Structure
Software College Northeastern University
Linked Lists: Cursor Implementation
Global array of structures
Address: Array index
#define SpaceSize 1000
typedef struct Node{
ElementType data;
int next;
}Node,CursorSpace[Spacesize];
Data Structure
0
1
1
2
2
3
3
4
4
5
5
6
7
7
8
8
9
9
10
10
0
Software College Northeastern University
6
Linked Lists: Cursor Implementation
free list head
0
Simulation of malloc and free
Equivalent for malloc and free in cursor
space array:
Freelist: cells that are not in any lists
Use cell 0 as a header of freelist
A value of 0 for next is equivalent to NULL
Data Structure
Software College Northeastern University
header
1
1
2
2
3
3
4
4
5
5
6
7
7
8
8
9
9
10
10
0
6
Linked Lists: Cursor Implementation
CursorAlloc to simulate malloc()
0
1
0
freelist
2
1
2
1
header
1
2
3
2
3
3
4
3
4
4
5
4
5
5
6
5
6
6
7
8
9
10
Data Structure
freelist
7
6
8
7
9
10
0
8
9
10
7
8
9
10
0
Software College Northeastern University
Linked Lists: Cursor Implementation
int CursorAlloc(void)
{ //allocate a cell from freelist
int p;
p = CursorSpace[0].next;
CursorSpace[0].next = CursorSpace[p].next;
return p;
} //end of CursorAlloc
Data Structure
Software College Northeastern University
Linked Lists: Cursor Implementation
CursorFree to simulate Free()
0
freelist
8
0
1
header
2
1
freelist
header
4
2
2
c
3
2
c
3
3
b
4
3
b
5
4
e
5
4
e
8
5
g
6
5
g
6
6
f
7
6
f
7
7
d
1
7
d
1
8
9
8
9
9
10
9
10
10
0
10
0
Data Structure
Software College Northeastern University
Linked Lists: Cursor Implementation
void CursorFree(int p)
{ //release a cell to freelist
CursorSpace[p].next = CursorSpace[0].next;
CursorSpace[0].next = p;
} //end of CursorFree
Data Structure
Software College Northeastern University
Linked Lists: Cursor Implementation
Check if the node is tail node
CursorSpace[r].next != first
Status Insert(elementType e,List L, int p)
{
int Tmpcell;
Tmpcell = CursorAlloc();
if(Tmpcell == 0)
return ERROR;
CursorSpace[Tmpcell].data = e;
CursorSpace[Tmpcell].next = CursorSpace[p].next;
CursorSpace[p].next = Tmpcell;
return OK;
}
Data Structure
Software College Northeastern University
Linked Lists: Polynomial Implementation
Unbounded
struct Term {
Convenient to insert or delete
int coef;
int exp;
Term ( int c, int e ) { coef = c; exp = e; }
};
class Polynomial
{
List<Term> poly;
friend Polynomial & operator +
( Polynomial &, Polynomial &);
};
Data Structure
//构造函数
//加法
Software College Northeastern University
Polynomial Implementation:Adding(1)
AH = 1 - 10x6 + 2x8 +7x14
BH = - x4 + 10x6 - 3x10 + 8x14 +4x18
Data Structure
Software College Northeastern University
Polynomial Implementation:Adding(2)
Polynomial & operator + ( Polynomial & ah,
Polynomial & bh ) {
//多项式加法, 结果由ah表头结点指示
ListNode<Term> *pa, *pb, *pc, *p;
ListIterator<Term> Aiter ( ah.poly );
ListIterator<Term> Biter ( bh.poly );
//建立两个多项式对象 Aiter、Biter
pa = pc = Aiter.Firster( ); // ah 检测指针
pb = p = Biter.Firster ( ); // bh 检测指针
pa = Aiter.Next ( ); pb = Biter.Next ( );
// pa, pb 越过表头结点
Data
Structure p;
Software College Northeastern University
delete
Polynomial Implementation:Adding(3)
while ( Aiter.NotNull ( ) && Biter.NotNull ( ) )
switch ( compare ( pa→exp, pb→exp ) ) {
case ‘=’ :
// pa指数等于pb指数
pa→coef = pa→coef + pb→coef;
p = pb; pb = Biter.Next ( ); delete p;
if ( !pa→coef ) {
//指数相加结果为0
p = pa; pa = Aiter.Next ( );
delete p;
}
else {
//指数相加结果不为0
pc→link = pa; pc = pa; //链入结果链
pa = Aiter.Next ( );
Data Structure}
Software College Northeastern University
Polynomial Implementation:Adding(4)
}
}
break;
case ‘>’ :
// pa指数大于pb指数
pc→link = pb; pc = pb;
pb = Biter.Next ( ); break;
case ‘>’ :
// pa指数小于pb指数
pc→link = pa; pc = pa;
pa = Aiter.Next ( );
if ( Aiter.NotNull ( ) ) pc→link = pa;
else pc→link = pb;
Data Structure
Software College Northeastern University
Multilists
We can get even more complicated.
Suppose we have 11,000 students and 600 courses
at this university. We want to record every course
that a student takes and record every student in a
class. This would require an 11,000 x 600 array,
which is huge. Furthermore, most of the entries in
the array would be empty!
S1
S2
S3
S4
S5
.
.
Data Structure
C1 C2………………………………………….
Software College Northeastern University
Sparse Matrix:array of Triple
6
0 12 9 0 0 0 0
0 0 0 0 0 0 0
A=
Changes to
17
-3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 -7 0 0 0
Problem:
It’s Hard to
insert and remove element.
Data Structure
7
8
row col value
0
1
2
3
4
5
6
7
8
0 1 12
2 2
9
2 0 -3
2 5 14
3 2 24
4 1 18
5 0 15
5
3
-7
Software College Northeastern University
A.rows
A.columns
A.Terms
A.elem
Inserting
(3,5,17)
Use Multilists Instead
C1
Cm
S1
S2
Sn
Data Structure
Software College Northeastern University
Multilists continued…
To see which students are in course C1, we
simply go down the first column of the multilist.
To see which courses student S1 is taking, we
simply go along the first row of the multilist.
Data Structure
Software College Northeastern University
Multilists:Node
head
next
head
raw
col
down
right
down
value
right
(a) 表头结点
(b) 非零元素结点
False
i
j
a[i][j]
(c) 建立a[i][j]结点
Data Structure
Software College Northeastern University
Multilists
Data Structure
Software College Northeastern University
Multilists:Implementation
enum Boolean { False, True };
struct Triple { int row, col; float value; };
class Matrix;
class MatrixNode {
//矩阵结点定义
friend class Matrix;
friend istream &operator >> ( istream &,
Matrix & );
//矩阵输入重载函数
private:
MatrixNode *down, *right;
//列/行链指针
Boolean head;
//结点类型
Data Structure
Software College Northeastern University
Multilists:Implementation
}
Union { Triple triple; MatrixNode *next; }
//矩阵元素结点(False)或链头结点(True)
MatrixNode ( Boolean, Triple* );
//结点构造函数
MatrixNode::MatrixNode ( Boolean b, Triple *t ) {
//矩阵结点构造函数
head = b;
//结点类型
if ( b ) { right = next = this; }
else triple = *t;
}
Data Structure
Software College Northeastern University
Multilists:Implementation
typedef MatrixNode *MatrixNodePtr;
//一个指针数组, 用于建立稀疏矩阵
class Matrix {
friend istream& operator >> ( istream &,
Matrix & );
//矩阵输入
public:
~Matrix ( );
//析构函数
private:
MatrixNode *headnode; //稀疏矩阵的表头
};
Data Structure
Software College Northeastern University
Implementation of Sparse matrix:Construction
Process:
(1)read column number and row number of a spare
matrix
(2)create header matrix,column headers,row
headers
(3)initialize the pointer of header
(4)Iteration
- read a triple of a nonzero element
- allocate a node from system
- link it into column linked list
- link it into row linked list
Data Structure
Software College Northeastern University
Multilists:Implementation
istream & operator
>> ( istream & is, Matrix & matrix ) {
Triple s; int p;
is >> s.row >> s.col >> s.value;
//输入矩阵的行数, 列数和非零元素个数
if ( s.row > s.col ) p = s.row;
else p = s.col;
//取行、列数大者
matrix.headnode =
//整个矩阵表头结点
new MatrixNode ( False, &s );
if ( !p ) {
//零矩阵时
matrix.headnode→right = matrix.headnode;
Data Structure
Software College Northeastern University
0
Data Structure
1
2
3
4
5
Software College Northeastern University
6
Multilists:Implementation
return is;
}
MatrixNodePtr *H = new MatrixNodePtr [ p ];
//建立表头指针数组, 指向各链表的表头
for ( int i = 0; i < p; i++ )
H[i] = new MatrixNode ( True, 0 );
int CurrentRow = 0;
MatrixNode *last = H[0];
//当前行最后结点
for ( i = 0; i < s.value; i++ ) {
//建立矩阵
Triple t;
is >> t.row >> t.col >> t.value;
//输入非零元素的三元组
Data Structure
Software College Northeastern University
Multilists:Implementation
}
if ( t.row > CurrentRow ) {
//如果行号大于当前行,闭合当前行
last→right = H[CurrentRow];
CurrentRow = t.row;
last = H[CurrentRow];
}
last = last→right =
//链入当前行
new MatrixNode ( False, &t );
H[t.col]→next = H[t.col]→next→down
= last;
//链入列链表
last→right = H[CurrentRow];
//闭合最后一行
Software College Northeastern University
Data Structure
Multilists:Implementation
}
//闭合各列链表
for ( i = 0; i < s.col; i++ )
H[i]→next→down = H[i];
//链接所有表头结点
for ( i = 0; i < p-1; i++ )
H[i]→next =H[i+1];
H[p-1]→next = matrix.headnode;
matrix.headnode→right = H[0];
delete [ ] H;
return is;
Data Structure
Software College Northeastern University
List in STL
List: a container of STL
Interface:
Reversible traversal
Front Insertion Sequence
Back Insertion Sequence
Structure : Doubly Linked list
Data Structure
Software College Northeastern University
STL Example
A simple example using STL list
list is defined under namespace std in list file
Add the following two lines in your .h/.cpp
files
#include <list>
using namespace std;
list is a template container. In this example,
we store integer data into the list.
typedef list<int> LISTINT;
Data Structure
Software College Northeastern University
STL Example
int rgTest1[] = {5,6,7};
int rgTest2[] = {10,11,12};
LISTINT listInt;
LISTINT::iterator i;
// Insert one at a time
listInt.insert (listInt.begin(), 2);
listInt.insert (listInt.begin(), 1);
listInt.insert (listInt.end(), 3);
// output: 1 2 3
cout << "listInt:";
for (i = listInt.begin(); i != listInt.end(); i++)
cout << " " << *i;
cout << endl;
Data Structure
Software College Northeastern University
STL Example
// Insert 3 fours
listInt.insert (listInt.end(), 3, 4);
// output: 1 2 3 4 4 4
cout << "listInt:";
for (i = listInt.begin(); i != listInt.end(); ++i)
cout << " " << *i;
cout << endl;
// Insert an array at the end
listInt.insert (listInt.end(), rgTest1, rgTest1 + 3);
// output: 1 2 3 4 4 4 5 6 7
cout << "listInt:";
for (i = listInt.begin(); i != listInt.end(); ++i)
cout << " " << *i;
cout << endl;
Data Structure
Software College Northeastern University
STL Example
// Insert another LISTINT
LISTINT listAnother;
listAnother.insert (
listAnother.begin(),
rgTest2,
rgTest2+3);
listInt.insert (
listInt.end(),
listAnother.begin(),
listAnother.end());
// output: 1 2 3 4 4 4 5 6 7 10 11 12
cout << "listInt:";
for (i = listInt.begin(); i != listInt.end(); ++i)
cout << " " << *i;
<< endl;
Datacout
Structure
Software College Northeastern University
Exercises
1.Write a function to add two polynomials,Do not destroy the
input.Use a linked list implementation.If the polynomials have M
and N terms,respectively,What is the time complexity of your
program?
2.Write a program to find a particular element in a singly linked
list.Do this both recursively and nonrecursively,and compare
the running times,How big does the list have to be before the
recursive version crashes?
3.Write a nonrecursive procedure to reverse a single linked list
in O(N) time using constant extra space.
4.An Alternative to deletion strategy we have given is to use
lazy deletion.to delete an element,we merely mark it
deleted(using an extra bit field).The number of deleted and
Data Structure
Software College Northeastern University
Exercises
nondeleted elements in the list is kept as part of the data
structure.If there are as many as deleted elements as
nondeleted elements,we traverse the entie list,performing the
standard deletion algorithm on all marked nodes.
a.List the advantages and disadvantages of lazy deletion.
b.Write routines to implement the standard linked list
operations using laze deletion.
Please prepare the programming assignment of experiment 1.
Data Structure
Software College Northeastern University
© Copyright 2026 Paperzz