LeetCode 707.设计链表
思路
链表结点设置一个虚拟头结点,方便后续对链表的操作
代码实现
class MyLinkedList {
public:
struct ListNode{
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
MyLinkedList() {
size = 0;
dummyHead = new ListNode(0);
}
int get(int index) {
if(index > (size - 1) || index < 0){
return -1;
}
ListNode * cur = dummyHead->next;
while(index--) // 注意:--index会报错
{
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
ListNode *cur = dummyHead;
ListNode *newNode = new ListNode(val);
newNode->next = cur->next;
cur->next = newNode;
size++;
}
void addAtTail(int val) {
ListNode *newNode = new ListNode(val);
ListNode *cur = dummyHead;
while(cur->next != nullptr){
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size++;
}
void addAtIndex(int index, int val) {
if(index > size || index < 0){
return;
}
ListNode *newNode = new ListNode(val);
ListNode *cur = dummyHead;
while(index--){
cur = cur->next;
}
newNode->next = cur->next;
cur->next = newNode;
size++;
}
void deleteAtIndex(int index) {
if(index >= size || index < 0){ //注意:是 >= 否则报错
return;
}
ListNode *cur = dummyHead;
while(index--){
cur = cur->next;
}
ListNode *tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
size--;
}
private:
int size;
ListNode *dummyHead;
};
注意
-
1)需要区分NULL和nullptr:
-
NULL属于 C 语言中的宏,后来 C++11 引入了 nullptr 关键字,都用来表示空指针。
-
在C语言中,NULL是一个宏,被定义为空指针
#define NULL ((void *)0)
所以说NULL实际上是一个空指针,如果在C语言中写入以下代码,编译是没有问题的,因为在C语言中把空指针赋给int和char指针的时候,发生了隐式类型转换,把void指针转换成了相应类型的指针。
int *pi = NULL; char *pc = NULL;
以上代码如果使用C++编译器来编译则是会出错的,因为C++是强类型语言,void*是不能隐式转换成其他类型的指针的,所以实际上编译器提供的头文件做了相应的处理
-
在C++11中,NULL实际上是0,而nullptr表示空指针
#ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif
-
若C++中使用NULL代替0表示空指针,会在函数重载时出现问题
#include <iostream> using namespace std; void func(void* i) { cout << "func1" << endl; } void func(int i) { cout << "func2" << endl; } void main(int argc,char* argv[]) { func(NULL); func(nullptr); getchar(); }
结果为:
原因:
在这段代码中,我们对函数func进行可重载,参数分别是void*类型和int类型,但是运行结果却与我们使用NULL的初衷是相违背的,因为我们本来是想用NULL来代替空指针,但是在将NULL输入到函数中时,它却选择了int形参这个函数版本,所以是有问题的,这就是用NULL代替空指针在C++程序中的二义性。
-
-
2)代码中的size与index:
- 代码中的size包括原本真实的头结点,而index的范围是从0开始的,因此,在get函数中的为 index > (size-1),在addAtIndex函数中是index > size