1.单链表的查找
snode* slistfind(snode* stlheap, stltype x)
{while (stlheap){if (stlheap->data == x){return stlheap;}stlheap = stlheap->next;}return NULL;
}
2.单链表的插入操作
2.1在指定位置之前插入节点
void slistinsert(snode** stlheap, snode* pos, stltype x)
{assert(*stlheap && pos);//确保他俩都不为空if (*stlheap == pos){//相当于头插stlpushfront(stlheap, x);return;}snode* temp = (snode*)malloc(sizeof(snode));temp->data = x;temp->next = NULL;//开一个节点snode* temp1 = *stlheap;while (temp1->next != pos){temp1 = temp1->next;}//此时两个节点相邻temp1->next = temp;temp->next = pos;
}
说几个注意点,传的是2级指针,所以在需要改变头指针位置的时候,我们就解引用就行
在不需要改变头指针的值的时候,我们就用一个一级指针来代替它的作用,这样的结果是防止头指针位置变了,导致链表错位。
其次,在插入过程中,我们先判断,传入的指针是否为空。如果不为空就继续接下来的插入操作。
这里你可能好奇,pos指针是怎么来的,难道每次我都要循环遍历吗,其实不然,在我们前面写的查找操作中,就可以返回一个指针,可以将这个指针用到这里。
然后,对于插入的大部分操作,我们都是找到两个节点,然后改变他们两个加temp指针的值。
但如果没有3个节点,比如要在第一个节点之前插入呢?
此时问题就变成了头插的问题,而且这种问题是和我们正常插入操作矛盾的,因为他们需要的节点数量是不同的,因此,我们需要进行判断,来解决这类问题。
2.2在指定位置之后插入节点
void slistinsertafter(snode* pos, stltype x)
{assert(pos);snode* temp = (snode*)malloc(sizeof(snode));temp->data = x;temp->next = NULL;//开一个节点temp->next = pos->next;pos->next = temp;}
这里由于链表也是一种顺序表,而且我们是在指定位置之后插入数据,因此我们不需要头指针。
同时,这里我们只需要两个节点,因此也不需要考虑头插和尾插的关系。因此代码就变得很简单了。
2.3两种方式的时间复杂度分析
对于第一种方式,存在一个while循环,因此最坏情况下时间复杂度为O(n)
对于第二种方式,不存在循环等,时间复杂度为O(1)
3.单链表的删除操作
3.1删除指定位置的节点
void slisterase(snode** stlheap, snode* pos)
{assert(*stlheap && pos);if (pos == *stlheap){slistpopfront(stlheap);}else{snode* temp = *stlheap;while (temp->next != pos){temp = temp->next;}temp->next = pos->next;free(pos);pos = NULL;}
}
还是传2级指针,因为可能会删掉头节点,同样的这题我们还是要分类讨论,不再重复叙述原因了。
3.2删除指定位置之后的节点
void slisteraseafter(snode* pos)
{assert(pos);if (pos->next == NULL)return;snode* temp = pos->next;pos->next = pos->next->next;free(temp);temp = NULL;
}
这里同样也得分类讨论。
3.3两种方法的时间复杂度分析
第一种时间复杂度为O(n)
第二种时间复杂度为O(1)
4.链表的销毁
void slistdestory(snode** stlheap)
{snode* temp1 = *stlheap;while (temp1){snode* temp2 = temp1->next;free(temp1);temp1 = temp2;}*stlheap = NULL;
}
在这个过程中考虑,释放节点后,对应的next也会消失
因此顺序很重要,同时也考虑到了链表为空的情况
5.单链表的本质
其实单链表的本质就是一种顺序表,而且单链表只能从前向后遍历,不能从后向前遍历。
这也就导致了,删除或插入指定位置或当前位置之前的时间复杂度为O(n)
因为涉及到了一个循环遍历的问题。
删除或插入指定位置之后的操作时间复杂度为O(1)
因为不涉及到循环问题,直接从给的位置开始就可以了。