Doulist

Implement the class with given header.

As you guess, DouList means 逗list, very funny.

to_str() function means displaying the list with std::string, formating like [1, 2, 3, 4] , [2] or [] (empty list)(notice white-space)
operator<< means output the string from 'to_str()'

struct DouListNode is the node of DouList.

if you have any doubt in function of the member methods, take a look at STL.

中文描述概要:
0 大概是让你实现一个双头列表。
1 如果对成员函数的作用有疑问,参照STL的常规含义。
2 to_str()就是把list输出成标准字符串的形式。operator<<则打印to_str()得到的字符串。

include <iostream>
#include "DouList.h"
using namespace std;
 
DouList list1, list2;
 
void display() {
  cout << list1.empty() << ':' << list1 << endl;
  cout << list2.empty() << ':' << list2.to_str() << endl;
}
 
int main() {
  display();
  list1.push_front(894);
  list2.push_back(2136);
  cout << list1.front() << ',' << list1.back() << endl;
  cout << list2.front() << ',' << list2.back() << endl;
  display();
  list1.push_back(214);
  list2.push_front(931);
  cout << list1.front() << ',' << list1.back() << endl;
  cout << list2.front() << ',' << list2.back() << endl;
  display();
  for (int i = 0; i < 10; ++i) {
    int t;
    cin >> t;
    list1.push_back(t);
    list2.push_front(t);
  }
  display();
  for (int i = 0; i < 5; ++i) {
    list1.pop_front();
    list2.pop_back();
  }
  display();
 
  DouList list3(list1);
  list1 = list2;
  cout << list1 << endl;
  cout << list3 << endl;
  return 0;
}



#ifndef SSCPP2014_DOULIST_A_H
#define SSCPP2014_DOULIST_A_H
 
#include <string>
 
struct DouListNode {
  int elem;
  DouListNode *prev, *next;
  DouListNode(int e = 0, DouListNode *p = 0, DouListNode *n = 0) {
    elem = e;
    prev = p;
    next = n;
  }
};
 
class DouList {
  private:
    DouListNode *m_head, *m_tail;
  public:
    DouList();
    DouList(const DouList &src);
    ~DouList();
    void clear();
    bool empty() const;
    std::string to_str() const;
    int front() const;
    int back() const;
    void push_front(const int &e);
    void push_back(const int &e);
    void pop_front();
    void pop_back();
    void operator=(const DouList &other);
    friend std::ostream& operator<<(std::ostream &out,
           const DouList &list);
    // non-meaning static value
    static int _error_sign;  // for illegal front()/back()
};
 
#endif

My answer:

// Created by 小明 on 4/28/
// Copyright © 2016 小明 All rights reserved.
<span style="font-size:14px;">#include<iostream>
#include"DouList.h"
#include <string>
#include <sstream>
#include<assert.h>
using namespace std;


DouList::DouList() {
    m_head = NULL;
    m_tail = NULL;
}
void DouList::operator=(const DouList &a) {
        this->clear();
    if (a.m_head == NULL) {
        return;
    }
    DouListNode* p = a.m_head;
    while (p != NULL) {
        push_back(p->elem);
        p = p->next;
    }
}
DouList::DouList(const DouList &a) {
    m_head = NULL;
    m_tail = NULL;
    if (a.m_head == NULL) {
        return;
    }
       DouListNode* p = a.m_head;
    while (p != NULL) {
        this->push_back(p->elem);
        p = p->next;
    }
}
DouList::~DouList() {
    this->clear();
}
void DouList::clear() {
    DouListNode* p = m_head;
    DouListNode* q;
    while (p != NULL) {
        q = p;
        p = p->next;
        delete q;
    }
    m_tail = NULL;
    m_head = NULL;
}
bool DouList::empty() const {
    if (m_head == NULL||m_tail == NULL) {
        return true;
    }
    return false;
}
string DouList::to_str() const {
    string a = "";
    stringstream ss;
    if (m_head == NULL) {
        return "[]";
    } else if (m_head == m_tail&&m_head != NULL) {
        ss << m_head->elem;
        a += "[";
        a += ss.str();
        a += "]";
    } else {
    a += "[";
    DouListNode* p = m_head;
    while (p != NULL) {
        ss << p->elem;
        string temp;
        ss >> temp;
        a += temp;
        if (p != m_tail) {
        a += ", ";
        } else {
            a += "]";
        }
        ss.clear();
        p = p->next;
    }
}
    return a;
}
int DouList::front() const {
    assert(m_head != NULL);
    return m_head->elem;
}
int DouList::back() const {
    assert(m_tail != NULL);
    return m_tail->elem;
}
void DouList::push_front(const int &e) {
    if (m_head == NULL) {
        DouListNode* p = new DouListNode(e, NULL, NULL);
        m_head = p;
        m_tail = p;
    } else {
        DouListNode* p = new DouListNode(e);
        p->prev = NULL;
        p->next = m_head;
        m_head->prev = p;
        m_head = p;
    }
}</span>
<span style="font-size:14px;">
void DouList::push_back(const int &e) {
    if (m_tail == NULL) {
        DouListNode* p = new DouListNode(e);
        p->next = NULL;
        p->prev = NULL;
        m_head = p;
        m_tail = p;
    } else {
        DouListNode* p = new DouListNode(e, m_tail, NULL);
        m_tail->next = p;
        m_tail = p;
    }
}
void DouList::pop_front() {
    if (this->empty()) {
        return;
    } else if (m_head->next == NULL) {
        delete m_head;
        m_head = NULL;
        m_tail = NULL;
    } else {
        DouListNode* p = m_head->next;
        delete m_head;
        m_head = p;
        m_head->prev = NULL;
        p = NULL;
    }
}
void DouList::pop_back() {
    DouListNode* p = m_tail;
    if (m_tail != NULL) {
        m_tail = m_tail->prev;
        if (m_tail != NULL) {
             m_tail->next = NULL;
        } else {
            m_head = NULL;
        }
        delete p;
    }
    if (m_tail == NULL) {
        m_head = NULL;
    }
}

std::ostream& operator<<(std::ostream &out, const DouList &list) {
    out << list.to_str();
    return out;
}

int DouList::_error_sign = -1; //可不用,可用assert代替。</span>

Answer:

<span style="font-size:14px;">#include "DouList.h"
 
int DouList::_error_sign = -1;
 
DouList::DouList() {
  m_head = m_tail = 0;
}
 
DouList::DouList(const DouList &src) {
  m_head = m_tail = 0;
  *this = src;
}
 
DouList::~DouList() {
  this->clear();
}
 
void DouList::clear() {
  DouListNode *t;
  while (m_head) {
    t = m_head;
    m_head = m_head->next;
    delete t;
  }
  m_head = m_tail = 0;
}
 
bool DouList::empty() const {
  return m_head == 0 ? true : false;
}
 
std::string DouList::to_str() const {
  long long int tmp;
  std::string ret = "[";
  if (!this->empty()) {
    DouListNode *p = m_head->next;
    tmp = m_head->elem;
    ret += std::to_string(tmp);
    while (p) {
      tmp = p->elem;
      ret += ", " + std::to_string(tmp);
      p = p->next;
    }
  }
  ret += "]";
  return ret;
}
 
int DouList::front() const {
  if (!this->empty())
    return m_head->elem;
  else
    return _error_sign;
}
 
int DouList::back() const {
  if (!this->empty())
    return m_tail->elem;
  else
    return _error_sign;
}
 
void DouList::push_front(const int &e) {
  if (this->empty()) {
    m_head = m_tail = new DouListNode(e);
  } else {
    m_head->prev = new DouListNode(e, 0, m_head);
    m_head = m_head->prev;
  }
}
 
void DouList::push_back(const int &e) {
  if (this->empty()) {
    m_head = m_tail = new DouListNode(e);
  } else {
    m_tail->next = new DouListNode(e, m_tail);
    m_tail = m_tail->next;
  }
}
 
void DouList::pop_front() {
  if (this->empty())
    return;
  if (m_head == m_tail) {
    this->clear();
    return;
  } else {
    m_head = m_head->next;
    delete m_head->prev;
    m_head->prev = 0;
  }
}
 
void DouList::pop_back() {
  if (this->empty())
    return;
  if (m_head == m_tail) {
    this->clear();
  } else {
    m_tail = m_tail->prev;
    delete m_tail->next;
    m_tail->next = 0;
  }
}
 
void DouList::operator=(const DouList &other) {
  this->clear();
  m_head = m_tail = 0;
  if (other.empty())
    return;
  m_head = new DouListNode(other.m_head->elem);
  DouListNode *p = m_head;
  DouListNode *q = other.m_head->next;
  while (q) {
    p->next = new DouListNode(q->elem, p);
    p = p->next;
    q = q->next;
  }
  m_tail = p;
}
 
std::ostream& operator<<(std::ostream &out, const DouList &list) {
  out << list.to_str();
  return out;</span>
<span style="font-size:14px;">}
</span>
<span style="font-size:14px;">
</span>

反思与小结:

此提难点在于连接和删除操作时指针指向问题。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值