数据结构(二): 链表篇

free(pFree); //释放指针

return;

}

ListNode* pNode = the_head;

while (pNode->next != NULL && index>2){

pNode = pNode->next;

}

pFree = pNode->next; //再指向数据域就爆了

pNode->next=pNode->next->next; //这里要无缝衔接

free(pFree->pData); //先释放数据

free(pFree); //释放指针

}

//计算节点数

int Count(ListNode* the_head){

int count = 0;

ListNode*pNode = the_head;

while (pNode != NULL){

pNode = pNode->next;

count++;

}

return count;

}

//查找固定节点数据

ListNode* find(ListNode* the_head,int index){

ListNode* pNode=NULL;

pNode=the_head;

while(pNode != NULL && index){

pNode = pNode->next;

index–;

}

if(NULL == pNode){

cout<<“节点不存在”<<endl; //可以写日志里

}

return pNode;

}

};

//判断链表成环

bool is_ring(ListNode* a) {

ListNode* fast = a,*slow = a;

while (fast->get_next()) {

fast = fast->get_next();

if (fast->get_next() && slow->get_next() && fast != slow) {

fast = fast->get_next();

slow = slow->get_next();

}

if (fast == slow) {

return true;

}

}

return false;

}

//寻找入环点(默认成环)

int find_ring(ListNode* a) {

ListNode* fast = a->get_next()->get_next(), * slow = a->get_next();

while (fast != slow) {

fast = fast->get_next()->get_next();

slow = slow->get_next();

}

ListNode* slow2 = a;

while (fast != slow2) {

fast = fast->get_next()->get_next();

slow2 = slow2->get_next();

}

return slow2->get_value();

}

//原地翻转链表

ListNode* reverse_list(ListNode* a) {

ListNode* temp = new ListNode(0);

ListNode* h = NULL;

while(a->get_next()) {

temp = a;

a = a->get_next();

temp->add_node(h);

h = temp;

}

return temp;

}


尾插法

若将链表的左端固定,链表不断向右延伸,这种建立链表的方法称为尾插法。尾插法建立链表时,头指针固定不动,故必须设立一个搜索指针,向链表右边延伸,则整个算法中应设立三个链表指针,即头指针head、搜索指针p2、申请单元指针pl。尾插法最先得到的是头结点。

上面那个就是。


循环链表

在这里插入图片描述

寻找链表入环点

这个就比较需要脑子了,前边那个有手就行的。

我这个人,懒了点,来张现成的图吧。

在这里插入图片描述

看啊,在相遇之前呢,慢指针走的距离很好求的:L1 = D+S1;

快指针走的距离:设它在相遇前绕了n圈(n>1),那么:L2 = D+S1+n(S1+S2);

不过,还有一个等量关系,不要忽略掉,快指针的速度是慢指针的两倍,所以:L2 = 2L1;

那么就是:n(S1+S2)-S1 = D;

再转换一下就是:(n-1)(S1+S2)+S2 = D;

那也就是说,在相遇时候,把一个慢指针放在链表头,开始遍历,把一个慢指针放在相遇点开始转圈,当它俩相遇的时候,就是入环点了。

其实吧,用脑子想一开始很难想出来,用手想就快多了。

环的大小就不用我多说了吧,相遇之后,定住快指针,慢指针再绕一圈,再相遇的时候就是一圈了。


双向链表

在这里插入图片描述

参考单链表。


旋转链表

这个也比较有意思啊,题目时这样的:给定一个当链表,让你顺时针/逆时针旋转N个位置,要求原地旋转。

我讲一下思路吧:

1、将链表自成环。

2、从刚刚的头往后遍历N个位置,N为要旋转的数。

3、环断开。

解决。

秀吧,我就是觉得解法好玩,就收藏了。


STL 中的 List


每一个自己写过链表的人都知道,链表的节点和链表本身是分开设计的。

那我们来看一下List的节点设计:

template

struct __list_node

{

typedef void* void_pointer;

void_pointer prev;

void_pointer neet;

T date;

}

显而易见,这是一个通用双向链表的节点(如果对通用链表不了解,建议一定要自己动手设计一个)。

在这里插入图片描述

3、List基本函数使用

#include

typedef struct rect

{

···

}Rect;

list test; //声明一个链表,用于存放结构体数据

//如果想以其他方法初始化list列表,可以移步到下一行那个Vector的介绍


Rect a;

···

test.push_back(a);

test.push_front(a);

//头尾插入(双向链表)

//定点插入

test.insert(test.begin()+10,a); //在第十个节点之前插入a


//删除test头部的元素

test.erase(test.begin());

//删除test从头到尾的元素

test.erase(test.begin(), test.end());

test.pop_back();

test.pop_front();

其实增删还是推荐使用迭代器来,因为直接对数据进行操作会存在一定的危险。

在本文第三部分详细讲述了List迭代器操作增删。

除了这个函数:test.clear();这个函数安全得很,反正都清理掉了。


  1. 查、改

//迭代器

list::iterator p;

for (p = test.begin(); p != test.end(); p++)

cout << *p << " ";

要遍历还是首推迭代器。所有和遍历有关的还是用迭代器。


#include

sort(test.begin(),test.end()); //从头到尾,默认从小到大排序

//一般排序都是要自定义排序的:

bool Comp(const int &a,const int &b)

{

return a>b;

}

sort(test.begin(),test.end(),Comp); //这样就降序排序。


  1. 大小

test.size(); //容器已存入数据量

test.capacity(); //容器还能存多少数据量

//其实不用担心容器不够大,容量要满的时候它会自己扩容

  1. 其他

(1)压缩list

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

技术学习总结

学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。

最后面试分享

大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
ps://img-community.csdnimg.cn/images/e5c14a7895254671a72faed303032d36.jpg" alt=“img” style=“zoom: 33%;” />

技术学习总结

学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。

[外链图片转存中…(img-cpUbh2Z4-1713714994216)]

[外链图片转存中…(img-of1cbIoX-1713714994216)]

[外链图片转存中…(img-WDc1RCi3-1713714994217)]

最后面试分享

大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!

[外链图片转存中…(img-YJHCV52S-1713714994217)]

[外链图片转存中…(img-jqsbSWUF-1713714994217)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 9
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法是计算机科学和软件工程领域中非常重要的基础知识。数据结构是指组织和存储数据的方式,而算法则是解决问题的一系列步骤。在这里,我将简要介绍数据结构与算法的基础知识。 1. 数组(Array):是一种线性数据结构,可以存储相同类型的元素。数组的特点是可以通过索引快速访问元素。 2. 链表(Linked List):也是一种线性数据结构,不同于数组,链表的元素在内存中可以不连续存储,每个元素包含一个指向下一个元素的指针。 3. 栈(Stack):是一种后进先出(LIFO)的数据结构,只能在栈的一端进行插入和删除操作。 4. 队列(Queue):是一种先进先出(FIFO)的数据结构,只能在队列的一端进行插入操作,在另一端进行删除操作。 5. 树(Tree):是一种非线性数据结构,由节点和边组成。树的一个节点可以有多个子节点。 6. 图(Graph):也是一种非线性数据结构,由节点和边组成。不同于树,图中的节点之间可以有多个连接。 7. 排序算法:常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等,它们用于将一组元素按照特定的顺序进行排列。 8. 查找算法:常见的查找算法包括线性查找、分查找等,它们用于在一组元素中查找特定的值。 以上只是数据结构与算法的基础知识,还有许多其他重要的概念和算法,如哈希表、堆、图算法等。掌握数据结构与算法的基础知识可以帮助我们更好地理解和解决实际的计算机问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值