数据结构与算法
源码地址:https://github.com/whj198579
linkedlist
链表相关的算法
单链表倒置
linkedlist.c 实现单链表倒置非递归和递归两种算法
链表倒数第K个节点
backkth.c 链表倒数第K个节点,如果K大于链表长度则返回NULL
单链表的中间节点
findmid.c 求单链表的中间节点,如果偶数个节点,实现获取第一个节点和第二个节点两个算法
删除单链表的节点
deletenode.c 不知道单链表节点前驱的情况下,删除该节点(不考虑最后一个节点的情况)
增加单链表的节点
insertnode.c 给定单链表中非空节点,在该节点前面插入一个节点
判断单链表是否有环,起点以及环的长度
cycliclink.c 思路:
- 判断是否有环:一个快指针,一个慢指针,如果俩指针能重合,则说明有环儿;
- 环的长度:一个快指针,一个慢指针,俩指针重合的节点一定在环上,慢指针继续移动,再次与重合的节点重合时候即走完了一圈;
- 起点:需要三个指针,分析如图所示
- 慢指针走到A点时,假设快指针走到了B点,则有公式:2x=x+ns+s-y,即x=(n+1)*s-y;
- 因为慢指针每走一步,快指针走两步,所以他们会在距离A点y长度的M点重合,这个点是可以获得的;
- 当慢指针走到M点时,第三个指针从head出发;
- 当第三个指针走到A时候,慢指针向前走了x,因为之前慢指针在M点,所以走了x后,距离A点为y+x=(n+1)*s,正好在A点,即第三个指针与慢指针重合的结点即为起点;
判断两个单链表是否相交,求交点
crossingnode.c 判断两个单链表是否相交,求交点(两个链表都无环儿)
binarytree
二叉树的相关算法
二叉树前序、后序、中序遍历
order.c 实现递归和非递归算法,其中非递归算法需要用到栈的思想。
把二元查找树变成排序的双向链表
比如:
应转变为:
converttodoublelink.c 采用非递归实现算法。
二叉树中找出和为某一值的所有路径
比如在下面的二叉树中寻找和为22的所有路径:
结果为:10 12和10 5 7。
searchpath.c 采用递归实现算法。
stackandqueue
栈和队列的相关算法
设计包含min函数的栈
base.c 定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。
array
数组相关的算法
折半查找
折半查找针对排序后的数组。将排序后的数组做一下偏移,比如正常的排序数组为2 5 6 7 10 21 24 30 31,偏移后为30 31 2 5 6 7 10 21 24,查找便宜后数组里的某一项。
针对偏移数组的折半查找的思路为:
- 找到数组最小值,最大值在最小值前一个。那么需要查找的数如果小于数组的第一个值,则在最小值到最后一个值之间折半查找,否则在第一个值到最大值之间折半查找;
- 问题转化为查找数组的最小值,最大值和最小值构成了最小的偏转数组,利用折半查找的思想,如果折半后的数组是偏转数组,则一定包含最大值和最小值;
binarysearch.c 实现了普通的折半查找和针对偏移数组的折半查找。
求子数组的最大和
比如数组为1 -2 3 10 -4 7 2 -5,则和最大的子数组为3 10 -4 7 2,输出为18。
maxsubarray.c 利用贪婪算法实现。
排序
sort.c 实现插入排序、希尔排序、冒泡排序、快速排序、选择排序和归并排序。