数据结构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;}

链表的应用

  1. 多项式

这里写图片描述

多项式相加

这里写图片描述

相加算法思想

这里写图片描述

多项式存储结构
链式栈、队列、通常的单链表,也可以是连续存储结构。视具体应用需要而定。

多项式的运算
基本程序

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++语言描述专题系列 (十四) 波兰表达式

0 0