C++面试必备:链表反转与String类实现解析

需积分: 7 0 下载量 163 浏览量 更新于2024-07-31 收藏 40KB DOCX 举报
"这篇文件包含了两个C++面试中常见的问题:链表反转和自定义String类的实现。" 首先,我们来深入理解第一个面试题——链表反转。链表是一种线性数据结构,由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在C++中,链表通常通过结构体或类来表示。这里提到了两种反转链表的方法: 1. 遍历反转法:这种方法是迭代的,通过维护三个指针`pre`、`cur`和`ne`来实现。`pre`是前一个节点,`cur`是当前节点,`ne`是`cur`的下一个节点。在遍历过程中,`cur`的`next`指针指向前一个节点`pre`,然后更新`pre`和`cur`的值,继续遍历。最后,将头节点`head`的`next`设为`NULL`,并更新头节点为`pre`。 ```cpp struct Linka { int data; Linka* next; }; void reverse(Linka*& head) { if (head == NULL) return; Linka* pre, * cur, * ne; pre = head; cur = head->next; while (cur) { ne = cur->next; cur->next = pre; pre = cur; cur = ne; } head->next = NULL; head = pre; } ``` 2. 递归反转法:这种方法是递归的,每次递归调用都将链表的头部移动到下一个节点,直到链表为空或只有一个节点。然后,从递归返回的过程中反转节点的指针。这个方法需要注意在返回时将返回节点的`next`设为`NULL`以避免形成循环链表。 ```cpp Linka* reverse(Linka* p, Linka*& head) { if (p == NULL || p->next == NULL) { head = p; return p; } else { Linka* tmp = reverse(p->next, head); tmp->next = p; return p; } } ``` 接下来,第二个面试题涉及的是自定义一个String类。这个类应具有通用构造函数、拷贝构造函数、析构函数和赋值运算符重载。下面是这些成员函数的可能实现: ```cpp class String { public: // 通用构造函数 String(const char* str = NULL) { if (str == NULL) { m_data = new char[1]; m_data[0] = '\0'; } else { size_t len = strlen(str) + 1; m_data = new char[len]; strcpy(m_data, str); } } // 拷贝构造函数 String(const String& another) { size_t len = strlen(another.m_data) + 1; m_data = new char[len]; strcpy(m_data, another.m_data); } // 析构函数 ~String() { delete[] m_data; } // 赋值函数 String& operator=(const String& rhs) { if (this != &rhs) { delete[] m_data; size_t len = strlen(rhs.m_data) + 1; m_data = new char[len]; strcpy(m_data, rhs.m_data); } return *this; } private: char* m_data; // 用于保存字符串 }; ``` 这个String类实现了基本的字符串操作,如构造、拷贝、析构和赋值。在实现过程中,注意了内存管理,确保在必要时分配和释放内存,防止内存泄漏。同时,赋值运算符重载(`operator=`)遵循了深拷贝原则,避免了浅拷贝导致的问题。