目录
一、链表
Ⅰ、使用指针类型表示链表
1、移除链表元素
题目链接:
①、使用原链表进行操作
思路看下图注释
while(head != NULL && head ->val == val){
struct ListNode* tem = head;
head = head->next;
delete tem;
}
//分两部分,先去除头部可能有val的部分,然后去除后面的部分
//通常去除后面的部分通常会用一个新的指针去遍历去除。
struct ListNode* cur = head;
while(cur != NULL && cur ->next != NULL)
{
if(cur ->next ->val == val){
cur ->next = cur->next->next;
}
else cur = cur->next;
}
return head;
②、建立虚拟头节点操作
该方法将前面的思路直接合并。
struct ListNode* nhead = (struct ListNode*) malloc(sizeof(struct ListNode));
nhead ->next = head;
struct ListNode* tem = nhead;
while(tem != NULL && tem ->next!=NULL)
{
if(tem ->next->val == val){
tem ->next = tem ->next ->next;
}
else tem = tem ->next;
}
head = nhead->next;
return head;
//该方法较上面的好处是可以将移除头部元素和尾部元素的情况合并,一次遍历成功。
2、设计链表(熟悉链表的基本操作)
题目链接:
该题目较为全面的实现了基本插入、删除、查找、清空操作,用来熟悉链表非常好用。
//定义结构体
typedef struct MyLinkedList{
int val;
struct MyLinkedList* next;
} MyLinkedList;
//建立头节点
MyLinkedList* myLinkedListCreate() {
MyLinkedList* head = (MyLinkedList*)malloc(sizeof(MyLinkedList));
head->next = 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* head, int val) {
MyLinkedList* addhead = (MyLinkedList*)malloc(sizeof(MyLinkedList));
addhead->val = val;addhead->next = head->next;
head->next = addhead;
}
//尾部插法
void myLinkedListAddAtTail(MyLinkedList* head, int val) {
MyLinkedList* tem = head;
while(tem->next!=NULL){
tem = tem->next;
}
MyLinkedList* cur = (MyLinkedList*)malloc(sizeof(MyLinkedList));
cur->val = val;cur->next = NULL;
tem->next = cur;
}
//中间插入法
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;
}
}
}
//删除链表元素
void myLinkedListDeleteAtIndex(MyLinkedList* head, int index) {
if(index==0) {
MyLinkedList* tem = head->next;
if(tem!=NULL){
head->next = tem->next;
free(tem);
}
}
MyLinkedList* cur = head->next;
for(int i = 1;cur!=NULL;i++){
if(i==index){
MyLinkedList* temp = cur->next;
if(temp!=NULL){
cur->next = temp->next;
free(temp);
}
return;
}
else{
cur = cur->next;
}
}
}
//清空元素
void myLinkedListFree(MyLinkedList* head) {
while(head){
MyLinkedList* p2 = head;
head = head->next;
free(p2);
}
}
/**
* Your MyLinkedList struct will be instantiated and called as such:
* MyLinkedList* obj = myLinkedListCreate();
* int param_1 = myLinkedListGet(obj, index);
* myLinkedListAddAtHead(obj, val);
* myLinkedListAddAtTail(obj, val);
* myLinkedListAddAtIndex(obj, index, val);
* myLinkedListDeleteAtIndex(obj, index);
* myLinkedListFree(obj);
*/
3、双指针操作链表类型题目
①、反转链表
题目链接: