707. 设计链表
思路
题目中所给的接口参数都是一级指针,这存在着一个问题:当我们需要头插时,我们本应该会在函数体内部改变头指针,但是此时传递的参数是头指针而不是头指针的地址,所以我们没有办法再函数体内改变头指针。只要不是头插,我们就不需要改变头指针,只需要改变某一个节点的指针域,这是可以做到的,所以我们需要想一个办法将头节点和非头结点统一处理,我们可以定义一个虚拟头节点
,此时虚拟头节点
就是链表中的第一个节点
由题目所给的函数调用形式可知,obj就是指向
虚拟头节点
的指针,后续的接口函数中传递的指针都是指向虚拟头节点的指针
代码
typedef struct MyLinkedList {
int val;
struct MyLinkedList* next;
} MyLinkedList;
//此时创建的是虚拟头节点指针
MyLinkedList* myLinkedListCreate() {
MyLinkedList* dummyHead = (MyLinkedList*)malloc(sizeof(MyLinkedList));
dummyHead->next = NULL;
return dummyHead;
}
//obj是指向虚拟头节点的指针
int myLinkedListGet(MyLinkedList* obj, int index) {
MyLinkedList* cur = obj->next;
for (int i = 0; cur != NULL; i++) {
if (i == index) {
return cur->val;
}
else {
cur = cur->next;
}
}
return -1;
}
//obj是指向虚拟头节点的指针
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList* newHead = (MyLinkedList*)malloc(sizeof(MyLinkedList));
newHead->val = val;
//新头节点指向旧头节点
newHead->next = obj->next;
//虚拟头节点指向新头节点
obj->next = newHead;
return;
}
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
MyLinkedList* cur = obj;//cur是obj不是obj->next,防止obj->next为NULL
MyLinkedList* newTail = (MyLinkedList*)malloc(sizeof(MyLinkedList));
newTail->val = val;
newTail->next = NULL;
//寻找旧尾节点
while (cur->next) cur = cur->next;
//尾插
cur->next = newTail;
return;
}
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
//是否为头插
if (index == 0)
{
myLinkedListAddAtHead(obj, val);
return;
}
MyLinkedList* cur = obj;
for (int i = 0; cur != NULL; i++)
{
//找到插入的位置了
if (i == index)
{
MyLinkedList* newNode = (MyLinkedList*)malloc(sizeof(MyLinkedList));
newNode->val = val;
newNode->next = cur->next;
cur->next = newNode;
return;
}
else
{
cur = cur->next;
}
}
}
//obj是指向虚拟头节点的指针
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
MyLinkedList* cur = obj;
for (int i = 0; cur->next != NULL; i++)
{
if (i == index)
{
MyLinkedList* tmp = cur->next;
cur->next = cur->next->next;
free(tmp);
return;
}
else
{
cur = cur->next;
}
}
}
//obj是指向虚拟头节点的指针
void myLinkedListFree(MyLinkedList* obj) {
while (obj != NULL) {
MyLinkedList* tmp = obj;
obj = obj->next;
free(tmp);
}
}