Leetcode203移除链表元素
在原链表上修改,分两种情况:
若符合条件的节点是头节点,直接将头节点后移。
若符合条件的节点不是头节点,直接将前一节点指向后一节点。
struct ListNode* removeElements(struct ListNode* head, int val){
while(head&&head->val==val){
head=head->next;
}
struct ListNode* left;
left=head;
while(left&&left->next){
if(left->next->val==val){
left->next=left->next->next;
}
else{
left=left->next;
}
}
return head;
}
设置新的虚拟头节点:将原链表上所有节点同意当作非头节点处理。
struct ListNode* removeElements(struct ListNode* head, int val){
//结构体定义重命名为LNode
typedef struct ListNode LNode;
//声明一个虚拟头节点和指向虚拟头节点的头指针
LNode *ahead;
ahead=(LNode *)malloc(sizeof(LNode));
ahead->next=head;
LNode *left=ahead;
while(left&&left->next){
if (left->next->val==val){
left->next=left->next->next;
}
else{
left=left->next;
}
}
head=ahead->next;
return head;
}
Leetcode707设计链表
设计时使用单链表,使用虚拟头节点,方便将删除和插入操作进行统一
创造数组时需要建立一个指针,新建一个节点作为虚拟头节点
typedef struct {
int val;
struct MyLinkedList* next;
} MyLinkedList;
MyLinkedList* myLinkedListCreate() {
//这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!!
MyLinkedList* head;
head=(MyLinkedList *)malloc(sizeof(MyLinkedList));
head->next = NULL;//不可缺少
return head;
}
//get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-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;
}
//addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList));
nhead->val = val;
nhead->next = obj->next;
obj->next = nhead;
}
//addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
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;
}
//addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
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;
}
}
}
//deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
if (index == 0){
MyLinkedList *tmp = obj->next;
if (tmp != NULL){
obj->next = tmp->next;
}
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);
}
}
Leetcode206反转链表
双指针法:
struct ListNode* reverseList(struct ListNode* head){
//nhead的指针指向反转后的新的链表,初始为空
struct ListNode* nhead;
nhead=NULL;
//temp防止断链
struct ListNode* temp;
//循环链表
while(head){
//防止断链
temp=head->next;
//头插在新的链表上,达到反转目的
head->next=nhead;
//新的链表指针始终指向表头
nhead=head;
//head指向新的链表表头
head=temp;
}
//返回新的链表
return nhead;
}
递归实现:
写一个reverse函数实现双指针中的的while循环部分,达到反转链表的目的。
struct ListNode* reverse(struct ListNode* nhead, struct ListNode* head) {
//旧的链表头指针若为空,则输出新的链表
if(head==NULL){
return nhead;
}
//temp防止断链
struct ListNode* temp;
//防止断链
temp=head->next;
//头插在新的链表上,达到反转目的
head->next=nhead;
//新的链表指针始终指向表头
nhead=head;
//head指向新的链表表头
head=temp;
return reverse(nhead,head);
//以上三句也可以用下面这句表示return reverse(head,temp);
}
struct ListNode* reverseList(struct ListNode* head){
//nhead的指针指向反转后的新的链表,初始为空
struct ListNode* nhead;
nhead=NULL;
return reverse(nhead,head);
}