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
2. 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.
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)
newnode→link=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:
newnode→link=first→link;
first→link=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:
newnode→link=p→link;
p→link=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):
newnode→link=p→link;
p→link=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.
Translate them into c plus plus language(the first statement is setting the node to be deleted as the next node of p):
q=p→link;
p→link=q→link;
delete q;
if (p→link==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 ¤t->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 ¤t->data;}
- Data Structure Study: Linked List(Part A)
- HackerRank-Data Structure-linked list
- Single Linked List--Data Structure
- Double Linked List--Data Structure
- Linked Data structure
- data structure: static linked list / hash linking / an array based linked list
- C Linked List Data Structure Explained with an Example C Program
- 数据结构(Data Structure)(第三集)(链表(Linked List))
- [LinkedIn]linked List data structure so that add/insert, remove, get random in O(1) constant time
- PCM data flow - part 2: ASoC data structure
- reverse a linked list
- Reverse a linked list.
- Reverse a linked list
- Reverse A Linked List
- reverse a linked list
- Reverse a linked list
- reverse a linked list
- Implementing the skip list data structure
- 2. TortoiseGit安装与配置
- Vue.js提炼与升华
- 解决发送邮件时出现由www@localhost.localdomain代发的方法
- HTML知识点整理2
- 澄清误解,详解JS立即执行函数
- Data Structure Study: Linked List(Part A)
- 编程思想--编程的设计原则与设计模式
- RIP路由协议的理解
- 之前编写的Symfony教程已经可以下载啦
- hdoj1002解法
- 1003. 我要通过!(20)
- db2数据库还原
- c# 正则表达式的使用
- 闲话 - Melkman凸包算法