stackWithTemplate

  1. 重点理解swap, reverse两个函数的实现, 另外任何一个类中涉及到深赋值重点关注拷贝构造函数和clear函数,这两个函数是最容易出内存问题的,new和delete必须成对使用

下面是代码的实现

#ifndef STACK_H__
#define STACK_H__
#include<iostream>

template<typename T>
class Stack {
private:
  struct Node {
    T element;
    Node* next;
    Node(T ele, Node* n = NULL):element(ele), next(n) {}
    //  此处特别注意初始化列表与赋值符的不同
  };
  Node* top_node;
  size_t node_num;
public:
  Stack() {
    top_node = NULL;
    node_num = 0;
  }
  Stack(const Stack<T> & stack) {
    if (this == &stack) return;
    if (stack.top_node != NULL) {
    top_node = new Node(stack.top_node->element);
    Node* temp = stack.top_node->next;
    Node* p = top_node;
    while (temp) {
      p->next = new Node(temp->element);
      temp = temp->next;
      p = p->next;
    }
    node_num = stack.node_num;
    } else {
      top_node = NULL;
      node_num = 0;
    }
  }
  ~Stack() {
    this->clear();
  }
  bool empty() {
    return node_num == 0;
  }
  size_t size() const {
    return node_num;
  }
  T top() const {
    return top_node->element;
  }
  void push(T element) {
    Node* temp = new Node(element, top_node);
    top_node = temp;
    ++node_num;
  }
  void pop() {
    Node* temp;
    if (top_node != NULL) {
      temp = top_node;
      top_node = top_node->next;
      delete temp;
      --node_num;
    }
  }
  void swap(Stack & stack) {
    size_t temp = node_num;
    node_num = stack.node_num;
    stack.node_num = temp;
    Node* t = top_node;
    top_node = stack.top_node;
    stack.top_node = t;
  }
  void reverse() {
    // 利用中间栈的做法
    // if (node_num <= 1) return;
    // Stack temp;
    // Node* p = top_node;
    // while (p) {
    //   temp.push(p->element);
    //   p = p->next;
    // }
    // swap(temp);  // 巧

    // 直接用指针实现,不用中间栈的情况,这种实现方法更好也更加复杂
    if (node_num <= 1) return;
    Node* newtop = top_node;
    Node* t = top_node->next;
    newtop->next = NULL;
    while (t != NULL) {
      top_node = t;
      t = top_node->next;
      top_node->next = newtop;
      newtop = top_node;
    }
    top_node = newtop;

    // 下面的代码让我调试了几个小时始终找不出错误[事实证明我确实错了]
    // 注意透彻理解指针变动的过程

    // if (node_num <= 1) return;
    // Node* newtop = top_node;
    // newtop->next = NULL;
    // Node* t = top_node->next;
    // while (t != NULL) {
    //   top_node = t;
    //   t = top_node->next;
    //   top_node->next = newtop;
    //   newtop = top_node;
    // }
    // top_node = newtop;
  }
  void clear() {
    if (top_node != NULL) {
    Node* p = top_node;
    while (p) {
      Node* temp = p;
      p = p->next;
      delete temp;
    }
    }
    top_node = NULL;
    node_num = 0;
  }
};
#endif

重要代码段:

if (node_num <= 1) return;
Node* newtop = top_node;
Node* t = top_node->next;
newtop->next = NULL;
while (t != NULL) {
top_node = t;
t = top_node->next;
top_node->next = newtop;
newtop = top_node;
}
top_node = newtop;

1 swap中直接进行指针的交换,这就充分体现了指针的优势,不需要进行内存的复制粘贴,只需要交换指向内存的指针

2.clear 的另外一种实现方法:


void clear() {
if (empty()) return;
while (!empty())
pop();
top_node = NULL;
node_num = 0;
}

3. element(ele) 直接调用拷贝构造函数,例如: stack.push(Job(1)), 首先Job(1)调用构造函数创建了一个新的对象, 若使用element = ele; 则此时首先创建一个临时对象,然后调用拷贝构造函数,所以总共创建了两次. 若使用element(ele),则直接调用拷贝构造函数,总共创建了一次, 注意两者之间的不同,这也是为什么使用初始化列表比使用=好的原因.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值