代码随想录算法训练营第六期三天 203.移除链表元素 707.设计链表 206.反转链表
今天复习了链表的基础知识。以及基础的结构体的使用。
链表通常情况下分为带头节点的和不带头节点的。一般来说都是使用带头节点的。这样在操作手节点时比较统一,方便,好理解。
203.移除链表元素
在这里可以练习。不带头节点和带头节点的两种。分别不同的处理方式。比较容易上手。
707.设计链表
七百零七题把707题,把常用的写法都做了一遍。仍然有很多需要注意的地方例如在z和c加加,例如在如何去释放资源?这是需要注意的。(PS:不要把NULL写成了NUll)
以下是我自己写的代码。非常的新手。和大神写的代码一对比可以发现有一些边界条件上的设置不清晰,读起来让人费解。当然这部分代码仍然存在大量错误但想表达的意思是可以理解的。
typedef struct {
int val;
struct MyLinkedList* next;
} MyLinkedList;
MyLinkedList* myLinkedListCreate(); {
MyLinkedList* head = (MyLinkedList*)malloc(sizeof(MyLinkedList));
head->next = NULL;//写成NUll不会报错
return head;
}
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;
}
void myLinkedListAddAtHead(MyLinkedList * obj, int val) {
MyLinkedList* cur = obj->next;
MyLinkedList* newone = (MyLinkedList*)malloc(sizeof(MyLinkedList));
newone->val = val;
newone->next = cur;
obj->next = newone;
}
void myLinkedListAddAtTail(MyLinkedList * obj, int val) {
MyLinkedList* newone = (MyLinkedList*)malloc(sizeof(MyLinkedList));
MyLinkedList* cur = obj->next;
while (cur->next != NULL) {
cur = cur->next;
}
newone->val = val;
newone->next = NULL;
cur->next = newone;
}
void myLinkedListAddAtIndex(MyLinkedList * obj, int index, int val) {
MyLinkedList* newone = (MyLinkedList*)malloc(sizeof(MyLinkedList));
MyLinkedList* cur = obj->next;
for (int i = 0; i > index; i++)
{
cur = cur->next;
if (i == index) {
newone->val = val;
newone->next = cur->next;
cur->next = newone;
return;
}
else
{
return -1;
}
}
}
void myLinkedListDeleteAtIndex(MyLinkedList * obj, int index) {
MyLinkedList* cur = obj->next;
for (int i = 0; i > index; i++)
{
cur = cur->next;
if (i == index) {
MyLinkedList* temp=cur->next;
cur->next = cur->next->next;
free(temp);
return;
}
else
{
return -1;
}
}
}
void myLinkedListFree(MyLinkedList * obj) {
MyLinkedList* temp = obj->next;
free(obj);
while(temp!=NULL){
MyLinkedList* temp2 = temp->next;
free(temp);
temp = temp2;
}
return;
}
把错误留上边是方便嗯记录自己的思考过程
下面是不让人费解的正确的代码。
typedef struct {
int val;
struct MyLinkedList* next;
}MyLinkedList;
/** Initialize your data structure here. */
MyLinkedList* myLinkedListCreate() {
//这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!!
MyLinkedList* head = (MyLinkedList *)malloc(sizeof (MyLinkedList));
head->next = NULL;
return head;
}
/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
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;
}
/** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList));
nhead->val = val;
nhead->next = obj->next;
obj->next = nhead;
}
/** Append a node of value val to the last element of the linked list. */
void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
MyLinkedList *cur = obj;
while(cur->next != NULL){
cur = cur->next;
}
MyLinkedList *ntail = (MyLinkedList *)malloc(sizeof (MyLinkedList));
ntail->val = val;
ntail->next = NULL;
cur->next = ntail;
}
/** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */
void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
if (index == 0){
myLinkedListAddAtHead(obj, val);
return;
}
MyLinkedList *cur = obj->next;
for (int i = 1 ;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;
}
}
}
/** Delete the index-th node in the linked list, if the index is valid. */
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
if (index == 0){
MyLinkedList *tmp = obj->next;
if (tmp != NULL){
obj->next = tmp->next;
free(tmp)
}
return;
}
MyLinkedList *cur = obj->next;
for (int i = 1 ;cur != NULL && cur->next != NULL; i++){
if (i == index){
MyLinkedList *tmp = cur->next;
if (tmp != NULL) {
cur->next = tmp->next;
free(tmp);
}
return;
}
else{
cur = cur->next;
}
}
}
void myLinkedListFree(MyLinkedList* obj) {
while(obj != NULL){
MyLinkedList *tmp = obj;
obj = obj->next;
free(tmp);
}
}
206.反转链表
反转链表的双指针写法。非常容易理解。非常清晰。对照着再去理解。递归的写法。更轻松了。如果对于递归上还有些疑问的话可,可以去看《算法图解》这本小书上的对于递归的思考感觉可以。瞬间理清如何去拿捏递归思维。