数据结构C++语言描述专题系列 (四) 链式栈和队列
来源:互联网 发布:mysql 删除重复 编辑:程序博客网 时间:2024/05/22 06:41
1、指针与链表
一、指针
指针是一种数据类型,具有指针类型的变量称为指针变量。但事实上,可以将指针直接看成一种特殊的变量。首先,它与一般变量一样具有变量的三个基本要素:名字、类型和值,不同点主要在于类型和值上,指针命名与一般变量命名一样,都用标识符。
指针所存放的是某个变量的地址值,或者说它所表示的数据值是某个变量在内存中的地址值。通常所说的指针存放哪个变量的地址值,它就指向那个变量。
指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,因为任何指针它本身数据值的类型都是unsigned long int型。
空指针 NULL
当前不指向具体的对象,不同的系统会使编译取不同的NULL值。在PC中的BC或VC,都取值0。如果考虑到移植,不要养成把NULL当成为0的习惯。
二、链式结构
每一个结点的地址存放在它前面的结点的指针域中。
结点的定义struct Node {// data members Node_entry entry; Node *next;// constructors Node( ); Node(Node_entry item, Node *add_on = NULL);};
结点的构造函数(Constructors)Node ∷Node( ){ next = NULL;}Node ∷Node( Node_entry item, Node *add_on){ entry = item; next = add_on;}
在使用中,第二个构造函数的第二个参数可以按缺省处理,即可作为NULL。也就是说第二个构造函数有2种方法引用,2个参数或1个参数。第二种情况下,第二个参数取缺省值NULL。
例Node first_node(‘a’);Node *p0 = &first_node;Node *p1 = new Node(‘b’);p0->next = p1;Node *p2 = new Node(‘c’, p0);p1->next = p2;
2、链式栈
如何实现链式栈
链式栈的组织形式
与顺序存储的栈区别
链式栈类说明
class Stack{public: Stack( ); bool empty( ) const; Error_code push(const Stack_entry &item); Error_code pop( ); Error_code top(Stack_entry &item) const;protected: Node *top_node;};
链式栈的图示
链式栈的入栈运算
Error_code Stack ∷push(const Stack_entry &item)/* Post: Stack_entry item is added to the top of the Stack; returns success or returns a code of overflow if dynamic menory is exhausted */{ Node *new_top = new Node(item, top_node); if(new_top = = NULL) return overflow; top_node = new_top; return success;}
链式栈的出栈运算
Error_code Stack ∷pop( )/* Post: The top of the Stack is removed. If the Stack is empty the method returns underflow; otherwise it returns success */{ Node *old_top = top_node; if(top_node = = NULL) return underflow; top_node = old_top - >next; delete old_top; return success;}
关于链式栈运算的副作用问题
例 一、 for(int i= 1; i<1000000; i + +) { Stack small; small.push(some.data); }
每次迭代产生一个stack对象,数据加入到相应的存储空间。因为动态生成,前次存储的数据会成为碎片,积累到一定程度引起系统崩溃。引入析构函数(destructor)。
Stack ∷~Stack( )/* Post: The Stack is cleared. */{ while (!empty( )) pop( );}
产生垃圾(garbage)
例二、Stack outer_stack; for (int i = 0; i<1000000; i + +) { Stack inner_stack; inner_stack.push(some_data); inner_stack = outer_stack; }例三、void destroy_the_stack (Stack copy){}int main( ){ Stack vital_data; destroy_the_stack(vital_data);}
链式栈改进方法
赋值重载
void Stack:: operator = (const Stack &original) // Overload assignment/* Post: The Stack is reset as a copy of Stack original. */{ Node *new_top, *new_copy, *original_node = original.top_node; if (original_node = = NULL) new_top = NULL; else { // Duplicate the linked nodes new_copy = new_top = new Node(original_node − >entry); while (original_node −>next != NULL) { original_node = originaLnode − >next; new_copy − >next = new Node(original_node − >entry); new_copy = new_copy − >next; } } while (! empty( )) // Clean out old Stack entries pop( ); top_node = new_top; // and replace them with new entries.}
拷贝方法的改进
Stack:: Stack(const Stack &original) // copy constructor/* Post: The Stack is initialized as a copy of Stack original. */{ Node *new_copy, *original_node = original.top_node; if (original_node = = NULL) top_node = NULL; else { // 复制链式栈的结点 top_node = new_copy = new Node(original_node − >entry); while (original_node − >next ! = NULL) { original_node = original_node − >next; new_copy − >next = new Node(original_node − >entry); new_copy = new_copy − >next; } }}
修改后的链式栈说明
class Stack {public:// 标准的栈方法 Stack( ); bool empty( ) const; Error_code push(const Stack_entry &item); Error_code pop( ); Error_code top(Stack_entry &item) const;// 关于链式栈的安全的特殊方法 ~ Stack( ); Stack(const Stack &original); void operator = (const Stack &original);protected: Node *top_node;};
3、链式队列
链式队列的操作示意
链式队列的说明
class Queue {public:// standard Queue methods Queue( ); bool empty( ) const: Error_code append (const Queue_entry &item); Error_code serve( ); Error_code retrieve (Queue_entry &item) const;// safety features for linked structures ~ Queue( ): Queue (const Queue &original); void operator = (const Queue &Original); protected: Node *front, *rear; }:
链式队列的构造函数与入队列操作
构造函数
Queue:: Queue( )/* Post: The Queue is initialized to be empty */{ front = rear = NULL;}
入队列操作
Error_code Queue:: append (const Queue_entry &item)/* Post: Add item to the rear of the Queue and return a code of success or return a code of overflow if dynamic memory is exhausted. */{ Node *new_rear = new Node(item); if (new_rear = = NULL) return overflow; if (rear = = NULL) front = rear = new_rear; else {. rear - >next = new_rear; rear = new_rear; } return success;}
链式队列的出队列操作
Error_code Queue:: serve( )/* Post: The front of the Queue is removed. If the Queue is empty return an Error_code overflow. */{ if (front = = NULL) return underflow; Node *old_front = front; front = old_front - >next; if (front = = NULL) rear = NULL; delete old_front; return success:}
派生链式队列与其长度函数
class Extended_queue: public Queue {public: bool full( ) const; int size( ) const; void clear( ); Error_code serve_and_retrieve(Queue_entry &item);};int Extended_queue:: size( ) const/* post: return the number of entries in the Extended_queue. */{ Node *window = front; int count = 0; while(window ! = NULL) { window = window - >next; count + +; } return count;}
4、多项式及其计算
需要解决的问题:多项式的表示及计算算法。
struct Term { int degree; double coefficient; Term (int exponent = 0, double scalar = 0):};Term:: Term(int exponent, double scalar)/* Post: The Term is initialized with the given coefficient and exponent, or with default parameter values of 0. */{ degree = exponent; coefficient = scalar;}
链表的应用
- 多项式
多项式相加
相加算法思想
多项式存储结构
链式栈、队列、通常的单链表,也可以是连续存储结构。视具体应用需要而定。
多项式的运算
基本程序
int mainO/* Post: The program has executed simple polynomialarithmetic comitered by the user.Uses: The classes Stack and Polynomial and the functions introductiotions, do_command, and get_command. */{Stack stored_polynomials;introductionO;instructionsO;while (do_command(get_command(), stored_polynomials));}
多项式运算(do command命令)
bool do_command(char command. Stack &stored_polynomials)/* Pre: The first parameter specifies a valid calculator command.Post: The command specified by the first parameter has been applieStack of Polynomial objects given by the second parameter. Atrue is returned unless command == 'q'. A"^-" ' S-y*Uses: The c/asses Stack and Polynomial. */ D '‘{Polynomial p, q, r;switch (command) {case '?':p.readO;if (stored_polynomials.,push(p) == overflow)cout « "Warning: Stack full, lost polynomial" « endl;break; case '=':if (stored_polynomials.empty())cout « "Stack empty" « endl;else {stored_polynomials.top(p);p.printO;}break;case'+':if (storecLpolynomials.emptyO)cout« "Stack empty" « endl;else{stored_polynomials.top(p); (?y{i-^a ^<%»/ |,storecLpolynomials.popO; 3; ^'if(stored_polynomials.empty()) {cout « "Stack has just one polynomial" « endl;stored_polynomials.push(p);}else{» stored_polynomials.top(q);stored_polynomials.pop();r.equals_sum(q, p); f '^- ^+ Pif (stored_polynomials.push(r) == overflow)cout « "Warning: Stack full, lost polynomial" « endl;}break;// Add options for further user commands.case 'q': ~^^-cout « "Calculation finished." « endl;return false;}return true;}
多项式类的说明
class Polynomial {public:void read();void printO;void equals_sum(Polynomial p. Polynomial q);void equals_difference(Polynomial p. Polynomial q);void equals_product(Polynomial p. Polynomial q);Error_code equals_quotient(Polynomial p. Polynomial q);private:double value;};class Polynomial: private Extended_queue { // Use private inheritance.public: . void read( ); void print( ) const; equals_sum(Polyoornial p. Polynomial q); void equals_difference(Polynomial p. Polynomial q); void equals_product(Polynomial p. Polynomial q); Error_code equals_quotient(Polynom»al p. Polynomial q); int degree() const; private: void mult_term(Polynomial p. Term t); }
多项式的打印
void Polynomial:: print( ) const/* Post: The Polynomial /s printed to cout */ Node *print_node = front; bool first_term= true; while (print.node != NULL) { Term &print_term = print_node->entry; if (first_term) { // In this case, suppress printing an initial'+'first_term = false; if (print_term.coefficient < 0) cout « " - "; }else if (print_term.coefficient < 0) cout « " - ";else cout « " + ";double r = (print_term.coefficient >= 0) ? print_term.coefficient: -(print_term.coefficient);if(r != 1) cout « r;if (print.term.degree > 1) cout « " X"" « print_term.degree;if (print_term. degree == 1) cout « " X";if (r == 1 && print_term.degree == 0) cout « " 1"; print.node = print_node->next; } if (first.term) cout « “0"; // Print 0 for an empty Polynomial. cout« end l;
多项式的读取
void Polynomial:: read( ) /* Post: The Polynomial /s read from cin. */ { clear( ); double coefficient; int last_exponent, exponent; bool first_term = true; cout « "Enter the coefficients and exponents for the polynomial, " « "one pair per line. Exponents must be in descending order." « endl « "Enter a coefficient of 0 or an exponent of 0 to terminate." «endl;
多项式的读取
do { cout « "coefficient? " « flush; cin »coefficient; if (coefficient != 0.0) { cout « "exponent? " « flush; cin » exponent; if ((! first_term && exponent >= last_exponent) || exponent < 0) { exponent =0; cout « "Bad exponent: Polynomial terminates without its last term « endl; } else { Term new_term(exponent, coefficient); append(new_term); first_term = false; } last_exponent = exponent; } } while (coefficient != 0.0 && exponent !=0);}
多项式加法
void Polynomial ::equals_sum(Polynomial p, Polynomial q)/* Post: The Polynomial object is reset as the sum of the two parameters. */{ dear( ); while (!p.empty( ) || !q.empty( )){ Term p_term, q_term; if (p.degree( ) > q.degree( )) { p.serve_and_retrieve(p_term); append(p_term); } else if (q.degree( ) > p.degre( )) { q.serve_and_retrieve(q_term); append(q_term); } else{ p.serve_and_retrieve<p_term); q.serve_and_retrieve(q_term); if (p_term.coefficient + q_term.coefficient ! = 0) { Term answer_term(p_term.degree, p_term.coefficient + q_term.coefficient); append(answer_term); } } }}
持续更新中。。。
数据结构C++语言描述专题系列 (一) 绪论
数据结构C++语言描述专题系列 (二) 栈
数据结构C++语言描述专题系列 (三) 队列
数据结构C++语言描述专题系列 (四) 链式栈和队列
数据结构C++语言描述专题系列 (五) 递归
数据结构C++语言描述专题系列 (六) 表与串
数据结构C++语言描述专题系列 (七) 查找
数据结构C++语言描述专题系列 (八) 排序
数据结构C++语言描述专题系列 (九) 表与信息检索
数据结构C++语言描述专题系列 (十) 二叉树
数据结构C++语言描述专题系列 (十一) 多路数
数据结构C++语言描述专题系列 (十二) 集合及其表示
数据结构C++语言描述专题系列 (十三) 图
数据结构C++语言描述专题系列 (十四) 波兰表达式
- 数据结构C++语言描述专题系列 (四) 链式栈和队列
- 数据结构C++语言描述专题系列 (三) 队列
- 数据结构C++语言描述专题系列 (二) 栈
- 数据结构C++语言描述专题系列 (一) 绪论
- 数据结构C++语言描述专题系列 (五) 递归
- 数据结构:栈的链式实现(C语言描述)
- 数据结构实现链式队列(C语言)
- 数据结构---C语言之队列的链式表示和实现(链队列)
- 数据结构与算法(Java语言描述)--栈和队列
- 数据结构——队列的链式实现(C语言)
- 数据结构之---C语言实现链式队列
- c语言数据结构实现-链式队列
- 链式队列(数据结构C#)
- 数据结构--链式栈(C语言)
- 链式栈 C语言数据结构
- 数据结构(C语言描述)读书笔记之队列
- 栈的链式实现(C语言描述)
- 数据结构学习系列六-链式栈(c++实现且应用模板)
- HDU5586 - Sum (最大子列和)
- android焦点分发无法获取到Down事件,却有Move和Up
- poj 2083 Fractal 【递归打印字符】
- lua字符串的分割函数
- CoreData: error: Failed to call designated initializer on NSManagedObject 的解决方法
- 数据结构C++语言描述专题系列 (四) 链式栈和队列
- 关于计算机视觉(随谈)
- Maven教程-坐标和依赖
- HDU5510 - Bazinga (kmp+暴力)
- 1008.数组元素循环右移问题
- Codeforces 601A Dijkstra最短路
- mod_proxy和mod_jk的区别
- Chromebox
- HDU5591 - ZYB's Game (简单博弈)