C++ Linked Lists   «Prev  Next»
Lesson 5A singly linked list
Objective The prepend() member function

C++ prepend() function

The C++ language does not have a built-in prepend() function for its standard containers like std::vector, std::list, or std::string.
However, you can achieve the prepend functionality in different ways:
  • For std::vector: You can use insert at the beginning of the vector:
    std::vector<int> vec = {1, 2, 3};
    vec.insert(vec.begin(), 0); // Prepends 0 to vec
    
  • For std::list: The push_front method is used:
    std::list<int> lst = {1, 2, 3};
    lst.push_front(0); // Prepends 0 to lst
    
For std::string: You can use insert at the beginning:
std::string str = "hello";
str.insert(0, "world"); // Prepends "world" to str

These methods allow you to prepend elements or strings to the containers, although they aren't named prepend. Remember, prepending might be inefficient for some containers like std::vector because it might involve moving all elements, whereas for std::list, it's a constant time operation.
Here's what you need to know about adding characters to the beginning of a C++ string:
Common Methods to "Prepend" in C++
  1. insert(): This is the most flexible way to insert characters at any position within a string, including the beginning:
    #include <string>
    #include <iostream>
    
    int main() {
       std::string str = "world";
       str.insert(0, "Hello, ");  // Inserts at index 0 (the beginning)
       std::cout << str << std::endl;  // Output: Hello, world
    }
    
  2. Operator + (Concatenation): You can concatenate strings, with the new string being placed at the front:
       std::string str = "world";
       std::string greeting = "Hello, ";
       std::string new_str = greeting + str;
       std::cout << new_str << std::endl;  // Output: Hello, world
       
  3. push_front() (for `std::deque`) If you are working with a std::deque (double-ended queue), you have a dedicated push_front() function for efficiently adding elements to the beginning.

    Here's an example of how to use the push_front() function with std::deque in C++:
    #include <iostream>
    #include <deque>
    
    int main() {
        // Create an empty deque of integers
        std::deque<int> myDeque;
    
        // Use push_front to add elements to the front of the deque
        myDeque.push_front(3); // Now deque is {3}
        myDeque.push_front(2); // Now deque is {2, 3}
        myDeque.push_front(1); // Now deque is {1, 2, 3}
    
        // Print the contents of the deque
        std::cout <<"Contents of deque after push_front operations: ";
        for (int i : myDeque) {
            std::cout <<i <<" ";
        }
        std::cout <<std::endl;
    
        return 0;
    }
    
    This example demonstrates:
    • Creating a std::deque of integers.
    • Using push_front() to add elements to the front of the deque, which is an efficient operation for std::deque because it doesn't need to shift elements like a std::vector would.
    • Iterating over the deque to print its contents, showing that the elements have indeed been added to the front.

    When you run this code, you should see the output:
    Contents of deque after push_front operations: 1 2 3
    
    This confirms that push_front() has added the elements in reverse order of insertion at the front of the deque.
Important Considerations
  • Efficiency: If you're prepending frequently within a loop, `insert()` could become less efficient due to repeatedly shifting existing characters in the string. In such cases, consider:
    • Reserving space: Use `string::reserve` to pre-allocate memory if you know the approximate final string size.
    • Using `std::deque`: If order is less important and you need frequent insertion at both the front and back, a `std::deque` might be more suitable.

Examine the prepend() member function of the singly linked list implementation.

The member function prepend() is used to build the list structure:

void slist::prepend(char c)
{
   slistelem*  temp = new slistelem;//make element
    
   temp -> next = h;        //link to slist
   temp -> data = c;
   h = temp;                   //update head of slist
}

A list element is allocated from free store, and its data member is initialized from the single argument c. Its link member next is set to the old list head. The head pointer h is then updated to point at this element as the new first element of the list.
Node Node::prepend(const std::string& tag, const Attributes& attributes, const std::string& text) {
	Node child = prepend(tag);
	for(auto attribute : attributes){
		child.pimpl_->append_attribute(attribute.first.c_str()) = attribute.second.c_str();
	}
	if(text.length()>0) child.pimpl_->append_child(pugi::node_pcdata).set_value(text.c_str());
	return child;
}

SEMrush Software