Data Structure Study: Linked List(Part A)

来源:互联网 发布:java如何遍历json数组 编辑:程序博客网 时间:2024/04/29 08:22

Basic Conceptions

Definition

A linked list is a linear collection of data elements, called nodes, each pointing to the next node by means of a pointer. It is a data structure consisting of a group of nodes which together represent a sequence. Under the simplest form, each node is composed of data and a reference (in other words, a link) to the next node in the sequence.

Advantages

  • Insertion and deletion node operations are easily implemented in a linked list.
  • Dynamic data structures such as stacks and queues can be implemented.
  • There is no need to define an initial size for a Linked list.
  • Items can be added or removed from the middle of list.

Disadvantages

  • They use more memory than arrays because of the storage used by their pointers.
  • Nodes in a linked list must be read in order from the beginning.
  • Difficulties arise in linked lists when it comes to reverse traversing.

Single Linked List

Characteristics

1. Node (item) representation
node representation
2. Linear structure
linear structure
3. Nodes stored in non-contiguous space
4. Extensible

ListNode Class implementation

A linked list is made up of a series of objects, called the nodes of the list. Because a list node is a distinct object (as opposed to simply a cell in an array), it is good practice to make a separate list node class.
The implementation of class ListNode is as following:

//"ListNode.h"#include <iostream>using namespace std;template <typename T> class ListNode{public:    T data;                 //value for this node    ListNode* link;         //pointer to next node in list    //constructors    ListNode(const T& item, ListNode* next = NULL):data(item), link(next){}    ListNode(ListNode* next = NULL):link(next){}    ListNode():link(NULL){}    ListNode<T>* nextNode() { return link; }    //get the address of next node (successor)    //new a node which points to "next" node    ListNode<T>* getNode(const T& item, ListNode<T>* next = NULL)    {        ListNode<T>* newNode = new ListNode<T>(item);        newNode->link = next;    }    //the following two functions will be discussed and implemented afterwards    void insertAfter(ListNode<T>* p);    void removeAfter();};

Dummy Node

Dummy Node(DN) has no specific meaning, it is usually at the beginning of a single linked list. The aim of dummy node is to unify and simplify the operations of linked list.
dummy node

ADT for Single Linked List with DN

//"SingleList.h"#include <iostream>#include "ListNode.h"using namespace std;template <typename T> class SingleList : public ListNode<T>{private:    ListNode<T>* first, last;public:    SingleList(const T& item);    ~SingleList();    void makeEmpty();    int length() const;    ListNode<T> *findThroughValue(T value);    ListNode<T> *findThroughIndex(int index);    int insert(T item, int position);    T* remove(int position);    T* get(int position);};

Implementation of some basic functions in SingleList Class are showed below:

/*in "SingleList.h"*///constructortemplate <typename T> SingleList<T>::SingleList(const T& item){    first = new ListNode<T>(item);    last = first;}//deconstructortemplate <typename T> SingleList<T>::~SingleList(){    makeEmpty();    delete first;    delete last;}//release the linked listtemplate <typename T> void SingleList<T>::makeEmpty(){    ListNode<T> *p;    while (first->link != NULL)    {        p = first->link;        first->link = p->link;    }    delete p;}//get the number of nodestemplate <typename T> int SingleList<T>::length() const{    ListNode<T> *p = first->link;    int counter = 0;    while (p != NULL)    {        p = p->link;        counter++;    }    delete p;    return counter;}//find a node that has a specific valuetemplate <typename T> ListNode<T>* SingleList<T>::findThroughValue(T value){    ListNode<T> *p = first;    while (p->data != value && p->link != NULL)        p = p->link;    return p;}//find the i-th node in the linked list (assuming that DN is the 0-th node)template <typename T> ListNode<T>* SingleList<T>::findThroughIndex(int index){    if (index < 0)        return NULL;    if (0 == index)        return first;    if (index > this->length())        return NULL;    ListNode<T> *p = first->link;    int counter = 0;    while (counter < index)    {        p = p->link;        counter++;    }    return p;}

Now we shall talk about the insertion and deletion of nodes in a linked list.

1. Insertion

The insertion can be divided into three different situations: insert a new node before the first node, inside a list, or after the last node.
In the first place, when we insert before the first node, whether the list has a dummy node should be considered. If it’s without dummy node, the address of first pointer will be changed. So the process will be this: (assuming that the name of the new node is newnode)
insert01

newnodelink=first;
first=newnode;

However, if the list has a dummy node, the address of first pointer doesn’t have to be changed. The process is much easier:
insert02

newnodelink=firstlink;
firstlink=newnode;

If we insert a node into the list (not head or tail), we can make an assumption that the pointer for the node in front of the new node is p, then the process is as following:
insert03

newnodelink=plink;
plink=newnode;

In the same way, for an insertion at the tail of a list, the last pointer’s address should be changed (notice that initially p->link = NULL, and so the first step can be regarded as newnode->link = NULL = p->link):
insert04

newnodelink=plink;
plink=newnode;
last=newnode;

The implementation of insertion is:

/*in "ListNode.h"*///insert a new node p after the current nodetemplate <typename T> void ListNode<T>::insertAfter(ListNode<T>* p){    p->link = link;    link = p;}
/*in "SingleList"*///insert a new node (with data equals item) before the position-th node//if the insertion succeeded, the return value is 0, otherwise 1template <typename T> int SingleList<T>::insert(T item, int position){    ListNode<T> *p = findThroughIndex(position - 1);    if (NULL == p)        return 0;    ListNode<T> *newnode = getNode(item, p->link);    if (NULL == p->link)        last = newnode;    p->link = newnode;    return 1;}
2. Deletion

In this passage, we will only discuss the deletion which happens in a list with DN. (The deletion of list without DN can be deduced by readers yourselves)
In the same way, it is divided by two conditions: whether it is an empty list after the deletion or not. If we assume the pointer towards the node to be deleted is q and the pointer before it is p, we can see the process through the following two pictures.
removal01
removal02
Translate them into c plus plus language(the first statement is setting the node to be deleted as the next node of p):

q=plink;
plink=qlink;
delete q;
if (plink==NULL)  last=p;

The implementation is as follows:

/*in "ListNode.h"*///delete the node after the current nodetemplate <typename T> void ListNode<T>::removeAfter(){    ListNode<T> *tempptr = link;    if (tempptr == NULL)        return;    link = tempptr->link;    delete tempptr;    return;}
/*in "SingleList.h"*///remove the position-th nodetemplate <typename T> T* SingleList<T>::remove(int position){    ListNode<T> *p = findThroughIndex(position - 1);    if (NULL == p)        return NULL;    ListNode<T> *q = p->link;    T value = q->data;    p->link = q->link;    delete q;    if (NULL == p->link)        last = p;    return &value;}

Iterator for Single Linked List

Definition for iterator:

In computer programming, an iterator is an object that enables a programmer to traverse a container, particularly lists.

Iterator Class has the following four principles:
- Derived class of SingleList class (or friend class of ListNode class and SingleList class)
- Iterator class can refer existing SingleList object
- Variable: current position (Keep the position of current node in the list)
- provide some methods for testing and searching

ADT for ListIterator

/*"ListIterator.h"*/#include<iostream>#include"SingleList.h";using namespace std;template <typename T> class ListIterator : public SingleList<T>{public:    ListIterator(const SingleList<T> &l) :list(l), current(l.findThroughIndex(0)) {}    bool notNull();    bool nextNotNull();    ListNode<T>* first();    ListNode<T>* next();private:    SingleList<T> &list;    ListNode<T> *current;};

Implementation of functions in the iterator

/*in "ListIterator.h"*///judging whether the current node existstemplate <typename T> bool ListIterator<T>::notNull(){    if (current != NULL)        return true;    return false;}//judging whether the next node of current node existstemplate <typename T> bool ListIterator<T>::nextNotNull(){    if (current != NULL && current->nextNode != NULL)        return true;    return false;}//initialize the current pointertemplate <typename T> ListNode<T>* ListIterator<T>::first(){    current = list.findThroughIndex(0);    return &current->data;}//select the next node of current node to be current nodetemplate <typename T> ListNode<T>* ListIterator<T>::next(){    if (current == NULL || current->link == NULL)    {        current = NULL;        return NULL;    }    current = current->link;    return &current->data;}
0 0
原创粉丝点击