1.第一个题目:移除链表里面的元素
移除链表里面的指定数值的这个元素,也就是这个输入的数据里面包含了我们需要删除的这个数据;
下面的这个是代码:我说一下这个思路,就是我们搞了一个新的链表,原来的这个链表里面不是val的元素都会插入到我们的这个新的链表里面去,最后返回我们的这个新的链表;下面详细分析一下代码和可能遇到的问题;
1)先定义这个newtail和newhead表示的就是我们的新链表的头结点和尾结点,刚开始设置为null即可;
2)pcur是用来对于我们的原来的链表进行遍历操作的,因此是被head赋值,这个head是我们的函数的形参哈
3)pcur进行遍历,条件就是不为空,遇到不是val的元素进行插入即可;
4)插入也分情况,如果第一次插入,就是尾插,也就是newhead==null,这个时候我们是第一个插入的冤元素,因此这个newhead,newtail指向的都是这个位置;
else里面就是说,当已经存在元素的时候,我们需要把这个pcur传递给我们的新链表的尾结点的下一个位置,然后这个newtail进行挪动即可;
5)if之后,只是进行一次,我们需要这个pcur不断的移动,进行遍历;
6)当我们直接返回的时候,就会报错,因为这个时候我们的新链表的微元素指向的还是原来的节点,因此我们需要置为空值;
7)这个时候还会报错,是因为空链表的情况下我们不可以直接解引用,需要判断是不是空的;
8)我自己犯的错误,就是第二行的函数代码写成了newtail=newtail=NULL,这个时候不断的提示报错,说是这个空指针啥的,修改之后就没有了,可能是这个运算符的优先级的问题,哈哈,注意一下;
typedef struct ListNode listnode;
struct ListNode* removeElements(struct ListNode* head, int val)
{
listnode* newhead,*newtail;
newhead=newtail=NULL;
listnode* pcur=head;
while(pcur)
{
if(pcur->val!=val)
{
if(newhead==NULL)
{
newhead=newtail=pcur;
}
else{
newtail->next=pcur;
newtail=newtail->next;
}
}
pcur=pcur->next;
}
if(newtail)
{
newtail->next=NULL;
}
return newhead;
}
2.第二个题目:翻转链表
下面的这个思路我们简单的介绍一下
下面的这个解法应该是非常简单的一个解决方法,但是不是所有的人都可以想到这个解决的方案,哈哈;
就是定义三个指针,n1,n2,n3通过指针的这个移动和这个指针的指向的变化,就可以解决我们的问题啦;
typedef struct ListNode listnode;
struct ListNode* reverseList(struct ListNode* head) {
listnode* n1,*n2,*n3;
if(head==NULL){
return head;
}
n1=NULL,n2=head,n3=n2->next;
while(n2){
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
n3=n3->next;
}
return n1;
}
为了方便大家进行理解,我使用作图软件花了这个草图,方便去说明问题:
刚开始的时候,我们的n1指向的事空的,n2指向的事我们的头结点,n3就是n2的下一个节点,然后我们的这个n2指向n1,接下来就是这个指针的移动过程,就是n1挪动到这个n2的位置上面去,n2挪动到这个n3上面的位置去,n3继续向后面进行移动即可,这个时候我们的指针的指向就发生了变化;
接下来实际上就是对于上面的这个过程的重复操作:就是不断的n2指向我们的n1修改这个指针的指向,然后就是全体向后进行移动,n1挪动到这个n2位置,n2挪动到这个n3的位置即可;
然后我们看一下这个结束的条件,大家是可以明显的发现:当我们的这个指针走着走着,一直到这个n2是空的时候,我们的这个过程就结束了,因此我们也就知道了这个循环结束的判断的条件;
接下来结合着看一下这个代码的内容,n1n2n3的定义肯定是没有问题的,while(n2)就是想要说明这个n2不是空值的时候,我们的这个操作是需要一直执行下去的;
因为这个最后结束的时候n3是空的情况下还是多走了一步的,因此这个需要判断一下,当我们的这个n3不是null的时候,这个操作才会执行,否则就会出现这个空指针的解引用的问题;
最后的时候,大家是可以发现,这个n2就是新的这个链表的头结点,我们直接返回即可;
但是这个链表可能是空的,这个时候我们的n2=head也就是说我们的这个n2是空的,这个时候n3=n2->next就会出现空值的解引用的问题,因此这个也是需要处理一下的,也就是说我们的head==null的时候,我们直接返回这个head也就是null直接返回即可;
typedef struct ListNode listnode;
struct ListNode* reverseList(struct ListNode* head) {
listnode* n1,*n2,*n3;
if(head==NULL){
return head;
}
n1=NULL,n2=head,n3=n2->next;
while(n2){
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
n3=n3->next;
}
return n1;
}