算法总结归纳(第二天)(数据结构线性表总结:链表、栈与队列、单调栈、单调队列、字符串)

目录

一、链表

Ⅰ、使用指针类型表示链表

1、移除链表元素

①、使用原链表进行操作

②、建立虚拟头节点操作

2、设计链表(熟悉链表的基本操作)

3、双指针操作链表类型题目

①、反转链表

②、两两交换链表中的元素

③、删除倒数第n个节点

Ⅱ、使用数组类型表示链表

1、单链表

2、双链表

二、栈与队列

Ⅰ、普通栈

1.使用数组实现栈

(重要)2、表达式求值(逆波兰表达式)

Ⅱ、队列

1、使用数组实现队列

Ⅲ、单调栈

Ⅳ、单调队列(滑动窗口)

三、字符串

Ⅰ、反转字符串系列

①、简单反转

1.反转Ⅰ

2、反转Ⅱ

②、复杂反转

1、反转单词


一、链表

Ⅰ、使用指针类型表示链表

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、双指针操作链表类型题目

①、反转链表

题目链接:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值