DS & A (Lists - Pointer Based)
| CHAPTER 10 |
Pre-requisite: C++, Knowledge on PointersTwo ways of implementing lists using pointers:
- Doubly Linked Linked List
- Singly Linked List
List ADT
- template<typename e> class List
- {
- //Empty the list
- virtual void clear() = 0;
- //Insert value of e into the list at a position before the current position
- virtual bool insert(const e&) = 0;
- //Append e to the list
- virtual bool append(const e&) = 0;
- //Remove element at the current position
- virtual bool remove(e&) = 0;
- //set current position to the beginning
- virtual void setBegin() = 0;
- //Set current position to the end
- virtual void setEnd() = 0;
- //Set current position to the previous element
- virtual void prev() = 0;
- //Set current position to the next element
- virtual void next() = 0;
- //Size of list to the left of current element
- virtual int leftLength() const = 0;
- //Size of list to the right of current element + 1(inclusion of current element)
- virtual int rightLength() const = 0;
- //Set current position to pos
- virtual bool setPos(int pos) = 0;
- //Get value at current position
- virtual bool getValue(e& item) const = 0;
- //Print list
- virtual void print() const = 0;
- };
Doubly Linked List Implementation
- template <typename e> class Node
- {
- public:
- e element;
- Node<e>* next;
- Node<e>* prev;
- Node(const e& elemValue,Node<e>* prevPtr = nullptr, Node<e>* nextPtr = nullptr)
- {
- element = elemValue;
- prev = prevPtr;
- next = nextPtr;
- }
- Node(Node<e>* prevPtr = nullptr, Node<e>* nextPtr = nullptr)
- {
- prev = prevPtr;
- next = nextPtr;
- }
- };
- template<typename e> class LList:public List<e>
- {
- private:
- Node<e>* head, *tail, *fence;
- int left_length, right_length;
- public:
- LList()
- {
- fence = tail = head = new Node<e>;
- left_length = right_length= 0;
- }
- bool insert(const e&) override;
- bool append(const e&) override;
- void setBegin() override;
- void setEnd() override;
- int leftLength() const override;
- int rightLength() const override;
- void prev() override;
- void next() override;
- bool remove(e&) override;
- void clear() override;
- bool setPos(int pos) override;
- bool getValue(e& item) const override;
- void print() const override;
- };
- The Implementation
- template<typename e>
- void LList<e>::clear()
- {
- delete fence,tail,head;
- LList();
- }
- template<typename e>
- bool LList<e>::insert(const e& item)
- {
- fence->next = new Node<e>(item,fence, fence-> next);
- if(tail == fence) tail = fence-> next;
- if (fence->next->next != nullptr)
- fence->next->next->prev = fence->next;
- right_length++;
- return true;
- }
- template<typename e>
- bool LList<e>::append(const e& item)
- {
- tail->next = new Node<e>(item,tail,tail->next);
- tail = tail->next;
- right_length++;
- return true;
- }
- template<typename e>
- bool LList<e>::remove(e& item)
- {
- if (fence->next == nullptr) return false;
- item = fence->next->element;
- Node<e>* temp = fence->next;
- if(temp->next == nullptr)
- tail = fence;
- else
- temp->next->prev = fence;
- fence->next = temp->next;
- delete temp;
- right_length--;
- return true;
- }
- template<typename e>
- void LList<e>::setBegin()
- {
- fence = head;
- right_length += left_length;
- left_length = 0;
- }
- template<typename e>
- void LList<e>::setEnd()
- {
- fence = tail;
- left_length += right_length;
- right_length = 0;
- }
- template<typename e>
- void LList<e>::prev()
- {
- if(fence == head) return;
- fence = fence->prev;
- }
- template<typename e>
- void LList<e>::next()
- {
- if(fence == tail) return;
- fence = fence->next;
- }
- template<typename e>
- int LList<e>::leftLength() const
- {
- return left_length;
- }
- template<typename e>
- int LList<e>::rightLength() const
- {
- return right_length;
- }
- template<typename e>
- bool LList<e>::setPos(int pos)
- {
- if(pos<0 && pos>left_length+right_length)
- {
- return false;
- }
- fence = head;
- for(int i=0; i<pos; i++)
- {
- fence = fence->next;
- left_length++;
- right_length--;
- }
- right_length = right_length+left_length-pos;
- left_length = pos;
- return true;
- }
- template<typename e>
- bool LList<e>::getValue(e& item) const
- {
- if(rightLength() == 0)
- {
- return false;
- }
- item = fence->next->element;
- return true;
- }
- template<typename e>
- void LList<e>::print() const
- {
- Node<e>* temp = head;
- std::cout<<"[ ";
- while(temp != fence)
- {
- std::cout<<temp->next->element<<" ";
- temp = temp->next;
- }
- std::cout<<"| ";
- while(temp != tail)
- {
- std::cout<<temp->next->element<<" ";
- temp=temp->next;
- }
- std::cout<<"]\n";
- }
Testing the Linked List implementation
- int main()
- {
- LList<int> newList; //creating a list object
- //Adding values to the list
- newList.append(1);
- newList.append(12);
- newList.append(21);
- newList.append(132);
- newList.append(321);
- newList.append(89);
- newList.append(567);
- newList.append(43);
- newList.append(233);
- newList.append(67);
- //The following values won't be added to the list because we defined the maxSize of the list to be 10
- newList.append(33);
- newList.append(54);
- newList.append(78);
- newList.print();
- newList.setPos(8); //changing the position of the fence (Remember that fence position begins from 0)
- std::cout<<"\nAfter setting position to 8\n";
- newList.print();
- int value; //temporary variable to store values
- //getting the previous value
- newList.prev(); //setting the fence to the PREVIOUS value
- newList.getValue(value); //value is passed by reference
- std::cout<<"\nAccessing Previous Value: "<<value<<std::endl;
- //getting the next value
- newList.next(); //setting the fence to the NEXT value
- newList.getValue(value); //value is passed by reference
- std::cout<<"Accessing Next Value : "<<value<<std::endl;
- //Removing the current value at fence
- newList.remove(value); //value here will store the value of the removed item from the list
- std::cout<<"\nAfter removing a value: \n";
- newList.print();
- std::cout<<"\nDisplaying Removed Value: "<<value<<std::endl;
- newList.setBegin(); //sets the fence to the beginning of the list
- std::cout<<"\nAfter setting position to the begin:\n";
- newList.print();
- //Inserting the removed value(i.e.,233) at the beginning of the List
- newList.insert(value);
- std::cout<<"\nAfter Inserting removed value to the list again:\n";
- newList.print();
- return 0;
- }
Singly Linked List Implementation
I leave that to you guys as an exercise. Try implementing it. All the best...
OR
You can join our Facebook group for the code
Pros and Cons Of Array-Based List
Pros:
- List size is not fixed. Hence, pre-allocation of memory is not necessary.
Cons:
- Every element requires overhead.
- Element access is complicated. Elements can't be accessed through indices.
( If you like the content here, follow TSP on social media to get notified on future updates)
Comments
Post a Comment