< data structure and algorithm analysis C + + description > Table/stack/queue

Source: Internet
Author: User

The main content of this chapter:

* Concept of abstract data type (ADT)

* Implement table/Stack/queue

* Learn about these three data structures in the application scenario

1. ADT

The Adt:abstract data type is an abstract mathematical model that defines a series of operations on the model. The person who uses it does not need to know how it is stored and only cares about its logical characteristics. You can use the ternary method to represent (d,s,p), D is the data object, S is the relationship between the data, P is the basic operation of the data, specific introduction, you can refer to the post: Click to open the link

2. Table ADT

The table's data is naturally a single element, and the relationships between elements are precursors and successors, operations including find/INSERT/delete operations.

2.1 Simple array implementations of tables

Arrays are statically allocated, lookups are spent constant Time (O (1)), and insertions and deletions are linear times (O (N)), and if the operation occurs at the end of the table, no time is required to move, and the constant Time (O (1)) is spent.

In C + +, an implementation--stl (Standard Template Library) with public data structures is included-the Standards Templates gallery.

Vector is based on an array implementation, can be copied and its occupied memory can be automatically recycled (through the destructor), you can adjust the size of the vector, as well as the capacity (capacity change is by allocating a new block of memory for the base array, then copy the old memory block into the new block, and then release the old block of memory). When inserting and deleting operations, a positional tag is required, where a generic iterator (in fact, a pointer) is used. There are three questions: how to get an iterator, what an iterator does, and which table ADT methods require an iterator as a formal parameter. The source code is as follows:

/* * Linear table implemented as an array */#include <iostream>using namespace std;template <typename object>class vector{private: int thesize;int Thecapacity;object * objects;public://constructor explicit Vector (int initsize = 0): thesize (initsize), Thecapac ity (initsize + space_capacity) {objects = new object[thecapacity];} Copy constructor vector (const vector &AMP;RHS): Objects (NULL) {operator= (RHS);} destructor ~vector () {delete[] objects;} Overloaded copy operator const VECTOR & operator= (const vector &AMP;RHS) {if (this = &rhs) {Delete [] objects;thesize = Rhs.size (); thecapacity = Rhs.capacity (); objects = new object[capacity ()];for (int k=0; k<size (); k++) {Objects[k] = Rhs.object S[K];}} return this;} Adjust the size of the vector void resize (int newSize) {if (NewSize > Thecapacity) Reserve (newsize*2 + 1); thesize = NewSize;} Adjust capacity void reserve (int newcapacity) {if (Newcapacity < thesize) Return;object *oldarray = objects;objects = new object[ newcapacity];for (int k=0; k < newcapacity; k++) objects[k] = Oldarray[k];thecapacity = Newcapacity;delete[] Oldarray;} Overloads take element characters []object & operator[] (int index) {return objects[index];} Overload takes an element character [], and the returned element is Lvalue, cannot modify const Object & operator[] (int index) const {return objects[index];} Determines whether the vector is empty bool empty () const {return size () ==0;} Gets the size of the vector int size () const {return thesize;} Gets the capacity of the vector int capacity () const {return thecapacity;} In the trailing insert element void push_back (const Object &x) {if (thesize = = thecapacity) {Reserve (2*thecapacity + 1);} Objects[thesize] = x;thesize++;} Eject trailing element void Pop_back () {thesize--;} Returns the trailing element const Object & Back () const {return objects[thesize-1];} Use pointers to define iterators typedef object * Iterator;typedef Const object * const_iterator;//get vector start iterator iterator begin () {return & Amp;objects[0];} Const_iterator begin () const {return &objects[0];} Gets the end of the vector iterator iterator end () {return &objects[size ()];} Const_iterator End () const {return &objects[size ()];} enum {space_capacity = 16};}; int main () {vector<int> test;test.push_back (2); Test.push_back (3)///through an iterator to print the contents of the Vector//todo: How to invoke the previously defined iterator (vector<int>::iterator ITR = Test.begin (); ITR < Test.end (); itr++) {//for (int i=0; i < test.size (); i++) {cout << *itr << "";} cout << Endl;bool vectorempty = Test.empty (); if (vectorempty) cout << "The vector is empty" << Endl;retur n 0;}

2.2 Realization of doubly linked list

Vectors are statically allocated arrays, and list spaces are not contiguous, indicating the relationship between elements through forward and back pointers. The source code is as follows:

#include <iostream>using namespace std;template <typename object>class list{private://linked list node definition, including data, Pointer to the precursor node, pointer to the back drive node, struct node {Object data; Node *prev; Node *next; Node (const object & D = Object (), node *p = NULL, node *n = null): Data (d), Prev (p), next (n) {}};p rivate:int thesize; Node *head; Node *tail;void init () {thesize = 0;head = new Node;tail = new Node;head->next = Tail;tail->prev = head;} Public://const_iterator defineclass const_iterator{protected:node *current;object & Retrieve () Const{return Current->data;} Const_iterator (Node *p): current (p) {}friend class list<object>;p ublic:const_iterator (): current (NULL) {}const Object & operator* () const {return retrieve ();} Prefix, ++itrconst_iterator & operator++ () {current = Current->next;return *this;} Suffix, Itr++const_iterator & operator++ (int) {Const_iterator old = *this;++ (*this); BOOL operator== (const const_iterator &AMP;RHS) Const{return current = = rhs.current;} BOOL operator!= (const const_iterator &AMP;RHS) Const {return! (*this = = RHS);}};/ /iterator defineclass iterator:public const_iterator{protected:iterator (Node *p): Const_iterator (p) {}friend class Lis T<object>;p Ublic:iterator () {}object & operator* () {return This->retrieve ();} Const Object & operator* () Const{return const_iterator::operator* ();} Iterator & operator++ () {this->current = This->current->next;return *this;} Iterator operator++ (int) {iterator old = *this;++ (*this), return old;}; Public:list () {init ();} List (const list & RHS) {init (); *this = RHS;} ~list () {clear ();d elete head;delete Tail;} Const List & operator= (const list & RHS) {if (this = = &AMP;RHS) return *this;clear (); for (const_iterator ITR = rhs. Begin (); ITR! = Rhs.end (); itr++) {push_back (*ITR);}} Iterator begin () {return iterator (head-> next); Const_iterator begin () Const{return const_iterator (Head->next); Iterator End () {return iterator (tail);} Const_iterator End () Const{return Const_iteRator (tail);} int size () Const{return thesize;} bool Empty () {return size () = = 0;} void Clear () {while (!empty ()) Pop_front ();} Object & Front () {return *begin ();} Const Object & Front () Const{return *begin ();} Object & Back () {return *--end ();} Const Object & Back () Const{return *--end ();} void Push_front (const Object &x) {insert (Begin (), x);} void push_back (const Object &x) {Insert (end (), x);} void Pop_front () {Erase (Begin ());} void Pop_back () {Erase (--end ());} Insert the node, create the node first, assign its prev and next, and then let P->prev->next and P->prev point to the newly created node iterator insert (iterator ITR, const Object &x) {node *p = Itr.current;thesize++;//return iterator (P->prev = P->prev->next = new Node (x, P->pre V, p)); Node *newnode = new node (x, P->prev, p);p->prev->next = Newnode;p->prev = Newnode;return iterator (newNode);} Delete the node and let P->prev->next point to P->next iterator erase (iterator ITR) {node *p = Itr.current;p->prev->next = P >next;p->next->prev = P->prev;iteraTor result (p->next);d elete p;thesize--;return result;} Iterator Erase (iterator start, iterator end) {for (iterator ITR = start; ITR! = end;) ITR = Erase (ITR); return end;}; int main () {list<int> test;test.push_back (1); Test.push_back (2); Test.push_back (3); for (LIST&LT;INT&GT;:: Iterator ITR = Test.begin (); ITR! = Test.end (); itr++) {cout << *itr << "";} cout << Endl;return 0;}
Issues: In writing code, there was a segment error, debugging with GDB is when performing an insert operation, P->prev->next this sentence will have a segment error, view P->prev point to null, found in the initialization function init, tail- >prev=head, wrote the Tail->next=head. That would be logically wrong.

3. Stack ADT

The stack is actually a table, but the operation is different. In the stack is a back-in, first-out (LIFO). Push is the element into the stack-input, pop is the element out of the stack, top is to take out the elements. In this way, the vector is used to implement the simple stack through inheritance.

#include "vector.cpp" Template<typename object>class stack:public vector<object>{public:void push (const Object & Data) {this->push_back (data);} void Pop () {this->pop_back ();} Const Object &top () {return this->back ();}}; int main () {stack<int> Test;test.push (1); Test.push (2); Test.pop (); int a = Test.top (); cout << "the top element Is "<< a << endl;return 0;}

Application: Balance symbol (rule of compiler check syntax-parentheses match)/suffix expression/function call. Let's talk about tail recursion here. Recursion is directly or indirectly called itself, that is, divide and conquer the idea, can make the program easier to understand, but will occupy the stack space, if recursive many times, will lead to the exhaustion of stack space. The test procedure is as follows:

#include <iostream>using namespace std;//loop output multiple elements void print (int start, int end) {if (start = = end) Return;cout < < start << endl;start++;p rint (start, end);} int main () {print (1,20000000); return 0;}
On my PC, there will be an error running up to 261,812 times. Use:

Ulimit-s
Can see the default stack space of the PC, my 8192, I will *2=16384 after the space, the number of runs will be doubled, to: 523989. Of course, now the compiler can do the corresponding optimization (GCC-O2), the tail recursion into a loop, a constant stack, specific posts can be found on the Qingshuihe side of the exchange paste: Click Open Link Click to open the link

3. Queue ADT

Similarly, the queue ADT is also a table, which is a first-in-one-out table (FIFO). You might consider implementing it with a loop array. The code is followed by the following: Go home tomorrow.

Application: queuing theory, etc.

                                                                                                                                                                                                                                                   


< data structure and algorithm analysis C + + description > Table/stack/queue

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.