2022寒假LeetCode刷题——Task01:链表
简介:作者基本是小白,所以此次刷题会是比较困难的过程,同时也是通过这次的组队学习捡拾起以前的知识,更重要是扩充和巩固。所以这篇blog篇幅可能较长且也有基础型知识的回顾,也是我在做题过程中一步步完成的记录。(有的没做出来参考了答案)
一、数组基础题目
(题号:0189)旋转数组
题目:给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。
首先要弄清楚的点:
vector和array的区别
C++的标准模板库(简称:STL)是一个13个容器的集合,vector是其中包含的一个容器。动态数组vector,他是容量大小动态变化的数组,定义vector对象的时候先不用指定数组的大小,有数据的话就往数组里面插入就可以了。vector内部自己管理存储空间。
vector的头文件和命名空间:
#include<vector> //注意,没有.h
using namespace std; //在std标准命名空间中
vector的定义
vector能够适应任何类型,他是一个类模板。
vector<int> arr_int; //定义了一个内部元素时int的动态数组;
vector<char> arr_char; //定义了一个内部元素是char的动态数组;
vector<CStudent> arr_student; //定义了一个内部元素是CStudent的动态数组;
vector<char*> arr_pchar; //定义了一个内部元素是char*的动态数组
补充:public、private、protected的区别
- public表示共有:类的数据成员和函数可以被该类对象和派生类访问
- private私有型:自己的类可以访问,但派生类不能访问。
- protected保护型:自身类和派生类可以访问相当于自身的private型成员,它同private的区别就是在派生类的区别上。
二、链表
链表(Linked List):一种线性表数据结构。它使用一组任意的存储单元(可以是连续的,也可以是不连续的),来存储一组具有相同类型的数据。
头指针:是指向链表中第一个结点的指针
首元结点:是指链表中存储第一个数据元素的结点
头结点:是在链表首元结点之前附设的一个结点
链表与数组的区别:数组在逻辑上和物理存储上都是连续的;链表在逻辑上是连续的,而在物理存储上不一定不是连续的,所以链表的一个结点存在数据域和存贮指向下一个结点地址的指针域。
遍历方式:数组是随机存取,链表是顺序存取。
首先补充单链表的基本操作:
- 定义和表示
- 销毁
- 求单链表表长
- 取值
- 查找(按值查找)
- 插入:在第i个结点前插入新结点
- 删除:删除第i个结点
- 单链表的建立(头插法、尾插法)
算法——单链表的定义和表示:
typedef struct Lnode{
//声明结点的类型和指向结点的指针类型
ElemType data; //结点的数据域
struct Lnode *next; //结点的指针域
}Lnode,*LinkList; //LinkList为指向结构体Lnode的指针类型
//单链表的初始化
/* (1)生成新结点作头结点,用头指针L指向头结点
(2)将头结点的指针域置空
*/
Status InitList_L(LinkList &L){
L = new LNode; //或L=(LinkList) malloc(sizeof(LNode));
L->next=NULL;
return OK;
}
算法——单链表的销毁:链表销毁后不存在
从头指针开始,依次释放所有结点
Status DestroyList_L(LinkList &L){
//销毁单链表L
Lnode *p; //或LinkList p;
while(L){
p = L;
L = L->next;
delete p;
}
return OK;
}
算法——单链表的清空:
链表仍存在,但链表中无元素,成为空链表(头指针和头结点仍然存在)。(依次释放所有结点,并将头结点指针域设置为空)
Status ClearList(LinkList &L){
//将L重置为空表
Lnode *p,*q; //或LinkList p,q;
p=L->next;
while(p){
//没到表尾
q=p->next;
delete p;
p=q;
}
L->next=NULL; //头结点指针域为空
return OK;
}
算法——求单链表的表长:
int ListLenght_L(LinkList L){
//返回L中数据元素个数
LinkList p;
p=L->next; //p指向第一个结点
i=0;
while(p){
//遍历单链表,统计总结点数
i++;
p=p->next;
}
return i;
}
算法——单链表的取值:
从链表的头指针出发,顺着链域next逐个结点往下搜索,直至搜索到第i个结点为止。
Status GetElem_L(LinkList,int i,ElemType &e){
//获取线性表中的某个数据元素的内容,通过变量e返回
p=L->next;j=1; //初始化
while(p&&j<i){
//向后扫描,直到p指向第i个元素或p为空
p=p->next;++j;
}
if(!p||j>i) return ERROR; //第i个元素不存在
e=p->data; //取第i个元素
return OK;
}//GetElem_L
算法——单链表的查找:
//按值查找——根据指定数据获取该数据所在的位置(地址)
Lnode *LocateELem_L(LinkList L, Elemtype e){
//在线性表L中查找值为e的数据元素
//找到,则返回L中值为e的数据元素,查找失败返回NULL
p=L->next;
while(p&&p->data!=e)
p=p->next;
return p;
}
//按值查找——根据指定数据获取该数据位置序号
int LocateElem_L(LinkList L, Elemtype e){
//返回L中值为e的数据元素的位置序号,查找失败返回0
p=L