数据结构与刷题——链表

数据结构与刷题——链表

数据结构与刷题——链表_第1张图片
数据结构与刷题——链表_第2张图片

单链表代码模板

代码实现单链表的方法有很多种,但是对于acm刷题来说,我们通常使用的是静态链表的方式,这样代码运行速度更快,防止被卡时间。

const int N = 100010;
int head; // 头指针
int e[N]; // e[i]表示第i个节点的
int ne[N];// 第i个节点的next指针,表示当前节点的直接后继的节点编号
int idx;//记录已经存储了多少个节点

void init()
{
	head = -1;//用-1表示空节点
	idx = 0;
}

//在第k个节点后面插入一个新节点,节点的值为x
void insert(int k,int x)
{
	e[idx] = x;
	ne[idx] = ne[k];
	ne[k] = idx++; 
}

// 删除第k+1个节点,即将将该节点的指针指向他的下一个元素
void delete_node(int k)
{
	ne[k] = ne[ne[k]];
}

void delete_head()
{
	head = ne[head];
}

//遍历过程
for(int i = head; i!=-1;i = ne[i])
{
	cout<<e[i]<<endl;
}

双链表

在实际的代码编写过程当中,我们也是直接使用静态链表来设置双链表,我们首先设置0号点和1号点为左右边界head,tail。之后我们就只需要在这两者之间插入节点构造双链表。
数据结构与刷题——链表_第3张图片
数据结构与刷题——链表_第4张图片

数据结构与刷题——链表_第5张图片

const int N = 100010;
int e[N];
int l[N];
int r[N];
int idx;

//初始化直接初始化出左右端点的下标,从而避免边界问题
void init()
{
    //初始化的左右别搞反了
    r[0] = 1;
    l[1] = 0;
    idx =2;
}

// 在k节点的右侧插入一个x,其实也相当于左侧插入节点
void add(int k,int x)
{
    e[idx] = x;
    //操作新节点的左右指针
    r[idx] = r[k];
    l[idx] = k;
    //再操作原数组的节点
    l[r[k]] = idx;
    r[k] = idx++;
}

void remove(int k)
{
    l[r[k]] = l[k]; //右节点的左侧,指向左节点
    r[l[k]] = r[k]; //左节点的右侧,指向右节点
}

经典例题

以上两种实现方式都是通过静态链表实现的,主要是来自y总的AcWing经典例题。
AcWing826. 单链表
AcWing827. 双链表
使用指针的实现方式,在leetcode当中用的比较多,这里给大家补充一些leetcode中出现的链表类型的题目,主要涉及到链表的遍历,双指针算法,和一些小技巧,高阶一点的题目会涉及到树和递归的问题。
我做的主要是leetcode上程序员面试经典和剑指offer的例题,不过个人感觉这些题也大部分涵盖了链表题型的大部分考法,而且题解也十分详细。
数据结构与刷题——链表_第6张图片
数据结构与刷题——链表_第7张图片

你可能感兴趣的:(数据结构)