链表篇(二)
设计链表
本题涉及到链表的基本操作:
链表节点值的获取,链表的插入(分为链表在表头插入和在表尾插入和指定位置插入)
题解
-
第一个要求——get()函数中,目的是获取链表中index个节点的值,先开始非常不理解这个while循环的工作原理,在文献查询之后,我明白了——
在链表中,index可视作一个计数器,告诉链表还有几次循环可以返回目标值,所以在index = 0 时跳出循环,cur不断向后迭代直到index = 0,完成查找。
-
第二个目标函数——addAtHead函数和addAtHead函数性质类似
- 对于
addAtHead
函数,只需要创建要插入的节点,而后替代虚拟头节点即可 - 对于
addAtTail
函数,多了一次遍历,及对于链表,在进行除头节点的插入、删除等操作时都需要遍历
- 对于
-
第三个目标函数——
addAtIndex(index,val)
即先将特殊情况去除——index超过链表长时返回为空。除此之外就是正常的插入操作。 -
第四个目标函数——
deleteAtIndex(index)
即先排除特殊情况,而后定义虚拟头节点后,对链表遍历,然后基础的删除链表节点操作。
代码:
class MyLinkedList {
public:
struct LinkNode{
int val;
LinkNode* next;
LinkNode(int val):val(val),next (NULL){}
};
MyLinkedList() {
dummyHead = new LinkNode(0);
size = 0;
}
int get(int index) {
if(index > (size - 1) || index < 0){
return -1;
}
LinkNode *cur = dummyHead->next;
while(index--){
cur = cur->next;
}
return cur->val;
}
void addAtHead(int val) {
LinkNode *newHeadNode = new LinkNode(val);
newHeadNode->next = dummyHead->next;
dummyHead->next = newHeadNode;
size++;
}
void addAtTail(int val) {
LinkNode* newTailNode = new LinkNode(val);
LinkNode* cur = dummyHead;
while(cur->next != NULL){
cur = cur->next;
}
cur->next = newTailNode;
size++;
}
void addAtIndex(int index, int val) {
if(index > size){
return;
}
LinkNode *newNode = new LinkNode(val);
LinkNode *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;
}
LinkNode *cur = dummyHead;
while(index--){
cur = cur->next;
}
LinkNode*tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
size--;
}
void PrintLinklist(){
LinkNode*cur =dummyHead;
while(cur->next != NULL){
cout << cur->next->val <<"";
cur = cur->next;
}
cout << endl;
}
private:
int size;
LinkNode *dummyHead;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
感想
在纠正bug的过程中,发现以下几个错误:
- 对每一个新建链表节点时,忘记加
new
——即一个动态内存,可以将链表视为一个不断加长的数组。而new
相当于一个全局变量用来创建对象,但要记得释放内存。 - size随着函数要求“++”/“–”。