Giter Club home page Giter Club logo

algo's Introduction

数据结构和算法必知必会的50个代码实现

微信搜索我的公众号“小争哥”,或者微信扫描下面二维码关注

关注微信公众号,回复”PDF“获取独家算法资料。

前Google工程师,10万人跟着学的《数据结构和算法之美》《设计模式之美》专栏作者

t2

数组

  • 实现一个支持动态扩容的数组
  • 实现一个大小固定的有序数组,支持动态增删改操作
  • 实现两个有序数组合并为一个有序数组

链表

  • 实现单链表、循环链表、双向链表,支持增删操作
  • 实现单链表反转
  • 实现两个有序的链表合并为一个有序链表
  • 实现求链表的中间结点

  • 用数组实现一个顺序栈
  • 用链表实现一个链式栈
  • 编程模拟实现一个浏览器的前进、后退功能

队列

  • 用数组实现一个顺序队列
  • 用链表实现一个链式队列
  • 实现一个循环队列

递归

  • 编程实现斐波那契数列求值f(n)=f(n-1)+f(n-2)
  • 编程实现求阶乘n!
  • 编程实现一组数据集合的全排列

排序

  • 实现归并排序、快速排序、插入排序、冒泡排序、选择排序
  • 编程实现O(n)时间复杂度内找到一组数据的第K大元素

二分查找

  • 实现一个有序数组的二分查找算法
  • 实现模糊二分查找算法(比如大于等于给定值的第一个元素)

散列表

  • 实现一个基于链表法解决冲突问题的散列表
  • 实现一个LRU缓存淘汰算法

字符串

  • 实现一个字符集,只包含a~z这26个英文字母的Trie树
  • 实现朴素的字符串匹配算法

二叉树

  • 实现一个二叉查找树,并且支持插入、删除、查找操作
  • 实现查找二叉查找树中某个节点的后继、前驱节点
  • 实现二叉树前、中、后序以及按层遍历

  • 实现一个小顶堆、大顶堆、优先级队列
  • 实现堆排序
  • 利用优先级队列合并K个有序数组
  • 求一组动态数据集合的最大Top K

  • 实现有向图、无向图、有权图、无权图的邻接矩阵和邻接表表示方法
  • 实现图的深度优先搜索、广度优先搜索
  • 实现Dijkstra算法、A*算法
  • 实现拓扑排序的Kahn算法、DFS算法

回溯

  • 利用回溯算法求解八皇后问题
  • 利用回溯算法求解0-1背包问题

分治

  • 利用分治算法求一组数据的逆序对个数

动态规划

  • 0-1背包问题
  • 最小路径和
  • 编程实现莱文斯坦最短编辑距离
  • 编程实现查找两个字符串的最长公共子序列
  • 编程实现一个数据序列的最长递增子序列

algo's People

Contributors

bkcarlos avatar caitlingao avatar chinalwb avatar email2liyang avatar git-zjx avatar hkesd avatar hkui avatar jerryderry avatar jiandandream avatar jiaoqiyuan avatar jinshaohui avatar jsrdxzw avatar kpatr1ck avatar liam0205 avatar lydongd avatar mvpcaozixiang avatar nameczz avatar peijiani avatar quanxing avatar richardweiyang avatar scissorsfeet avatar seasclouds avatar songzheng45 avatar wangzheng0822 avatar waynecui avatar yangchuz avatar yuanliandu avatar yuxiaoba avatar zackratos avatar zephylaci avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

algo's Issues

在java文件下的05_array文件下的GenericArray.java中获取对应 index 位置的元素get()方法中判断下标是否合法,调用了checkIndex方法,这里(inidex<0 || index > size),不应该是(index >= size)吗,数组下标是取不到size的

``
// 获取对应 index 位置的元素
public T get(int index) {
checkIndex(index);
return data[index];
}

private void checkIndex(int index) {
if(index < 0 || index > size) {
throw new IllegalArgumentException("Add failed! Require index >=0 and index <= size.");
}
}
``

Java 中的数组部分,插入元素的时候好像存在问题

if (index<0 || index>=count) return false;

刚开始插入元素的时候, index >= count 就会出问题,因为 count 初始化为 0,所以即使从头开始插入(即 index = 0),也插入不成功。换句话说根本插入不了元素,我觉得应该改成将 index >= count 改成 index > count:

if (index<0 || index > count) return false;

不知道理解对不对。

java中回文串实现的代码有问题

这里在回文串的实现有问题,在
leftLink = inverseLinkList(p);
System.out.println("左边第一个节点"+leftLink.data);
System.out.println("右边第一个节点"+p.next.data);
rightLink = p;
这段代码中leftLink和rightLink实际指向的是同一个引用,你反转时对p进行了操作,同样会影响到rightLink,实际你现在leftLink和 rightLink存放的都是左半部分的链表数据,判断回文串时永远会是true!

链表合并代码是错误的

listNode *mergeTwoLists(listNode *l1,listNode *l2)
{
listNode head = {0};
listNode *pRes = &head;

while(1)
{
	if(l1 == NULL)
	{
		pRes->next = l2;
	}

	if (l2 == NULL)
	{
		pRes->next = l1;
	}

	if(l1->val < l2->val)
	{
		pRes->next = l1;
		l1 = l1->next;
	}
	else
	{
		pRes->next = l2;
		l2 = l2->next;
	}
	pRes = pRes->next;
}

return head;

}

这个不是个死循环吗,怎么退出,怎么觉得写的很草率。

05_array/GenericArray.java中set(int index,T e)

05_array/GenericArray.java

public void set(int index, T e) {
// 此处调用checkIndex检查索引,修改值时索引应大于0或小于数组元素个数吧?
// 是否应改成index < 0 || index >= size
checkIndex(index);
data[index] = e;
}

private void checkIndex(int index) {
if (index < 0 || index > size) {
throw new IllegalArgumentException("Add failed! Require index >=0 and index <= size.");
}

JavaScript版本QuickSort快速排序排序100万个数时报错

调试环境:Chrome控制台
报错内容:Uncaught RangeError: Maximum call stack size exceeded
复现方式:将仓库中的JS版本快速排序代码在Chrome控制台进行调试,当数组长度为100万的时候,会出现超出最大调用次数的报错。

请问这个是什么原因造成的呢?

上传php代码的同学全局搜下冲突吧

php的composer.json和栈的algo\php\08_stack\Compute.php 源码中有冲突
<<<<<<< HEAD

            $arrLen = count($operStack);
            while ($operStack[$arrLen-1] === '/'){
                compute($numStack, $operStack);
                $arrLen--;
            }
            array_push($operStack, $arr[$i]);
            break;

upstream/master
case '/':

algo isIndexOutOfRange 判断问题

func (this *Array) isIndexOutOfRange(index uint) bool {
	if this.length != 0 && index > this.length {
		return true
	}
	return false
}

假如这里是数组length是3,如果取index==3的数值也应该是越界,这样理解的话index > this.length应该改为index >= this.length

python 中的数组部分,delete方法有问题

def delete(self, index: int) -> bool:
    if index >= self._count or index <= -self._count: return False
    self._data[index:-1] = self._data[index+1:]
    self._count -= 1

return True

这里delete虽然有移位,但是最后一个元素没有删除, 那就会引起删除之后insert失败的效果

i.e.
a = MyArray(6)
for i in range(6):
a.insert_to_tail(i)
print(a)
out: 0 1 2 3 4 5

a.delete(2)
print(a)
out: 0 1 3 4 5 ---> "其实索引为5的值还是5,只是没有显示"

a.insert_to_tail(7)
print(a)
out: 0 1 3 4 5 5 ---> "这里就出现了问题了"

单链表反转处是否可以更优?

`
// 单链表反转
public static Node reverse(Node list) {
Node headNode = null;

Node previousNode = null;
Node currentNode = list;
while (currentNode != null) {
  Node nextNode = currentNode.next;
  if (nextNode == null) {
    headNode = currentNode;
  }
  currentNode.next = previousNode;
  previousNode = currentNode;
  currentNode = nextNode;
}

return headNode;

}`

将while 循环中的if判断去了 再循环接受后再改变headNode是否会更优?
改为:
`
// 单链表反转
public static Node reverse(Node list) {
Node headNode = null;

Node previousNode = null;
Node currentNode = list;
while (currentNode != null) {
  Node nextNode = currentNode.next;
 
  currentNode.next = previousNode;
  previousNode = currentNode;
  currentNode = nextNode;
}
headNode = previousNode;
return headNode;

}`

翻转链表

def reverse(head):
reverse_head = None
current = head
while current:
reverse_head,reverse_head.next,current = current,reverse_head,current.next

为什么
reverse_head = current
reverse_head.next = reverse_head
current = current.next
这样会出错

关于链表删除倒数第k个节点的问题

`public static Node deleteLastKth(Node list, int k) {
Node fast = list;
int i = 1;
while (fast != null && i < k) {
fast = fast.next;
++i;
}

if (fast == null) return list; 

Node slow = list;
Node prev = null;
while (fast.next != null) {
  fast = fast.next;
  prev = slow;
  slow = slow.next;
}

if (prev == null) {
  list = list.next;
} else {
  prev.next = prev.next.next;
}
return list;

}`

感觉这段代码是删除正序的第k个节点的。不知道我的理解是否正确

python linkedlist中的两个删除方法有问题吧

def delete_by_node(self, node: Node):
    if not self._head or not node:
        return
    if node._next:   #这个是用来干嘛的,实在没搞懂
        node.data = node._next.data
        node._next = node._next._next
        return
    current = self._head
    while current and current._next != node:
        current = current._next
    if not current:
        return
    current._next = node._next

def delete_by_value(self, value: int):
    if not self._head or not value:
        return
    fake_head = Node(value + 1)
    fake_head.next = self._head
    prev, current = fake_head, self._head
    while current:  #没有停止的条件?什么时候停止?
        if current.data != value:
            prev._next = current
            prev = prev._next
        current = current._next
    if prev._next:
        prev._next = None
    self._head = fake_head._next

if node._next: #这个是用来干嘛的,实在没搞懂
node.data = node._next.data
node._next = node._next._next
return

while current: #没有停止的条件?什么时候停止?这里主要是用来做什么的?
if current.data != value:
prev._next = current
prev = prev._next
current = current._next

小白求指教!

go 17_skiplist 无法正确删除

//删除节点
func (sl *SkipList) Delete(v interface{}, score int) int {
	if nil == v {
		return 1
	}

	//查找前驱节点
	cur := sl.head
	//记录前驱路径
	update := [MAX_LEVEL]*skipListNode{}
	for i := sl.level - 1; i >= 0; i-- {
		update[i] = sl.head
		for nil != cur.forwards[i] {
                         //缺少判断
			if cur.forwards[i].score > score{
				break
			}
			if cur.forwards[i].score == score && cur.forwards[i].v == v {
				update[i] = cur
				break
			}
			cur = cur.forwards[i]
		}
	}

	cur = update[0].forwards[0]

	for i := cur.level - 1; i >= 0; i-- {

		if update[i] == sl.head && cur.forwards[i] == nil {
			sl.level = i
		}

		if nil == update[i].forwards[i] {
			update[i].forwards[i] = nil
		} else {
			update[i].forwards[i] = update[i].forwards[i].forwards[i]
		}
	}

	sl.length--

	return 0
}

single_list.c

在反转的时候 新的头节点(tmp)没有初始化,导致在反转后dump时 会出错 初始化后就可以修复了

DeleteByNode如果链表长度为1

单链表java代码中的

public void deleteByNode(Node p) {
    if (p == null || head == null) return;

    if (p == head) {
      head = head.next;
      return;
    }

    Node q = head;
    while (q != null && q.next != p) {
      q = q.next;
    }

    if (q == null) {
      return;
    }

    q.next = q.next.next;
  }

如果长度为1的话q.next是不是遍历不到???

python linkedlist deletebyvalue method 这个方法有问题

当链表当中self.__head.next 为None时,while循环调用node.next.data就会出错

`def delete_by_value(self, value):
'''在链表中删除指定存储数据的Node节点.
参数:
value:指定的存储数据
'''
if self.__head == None: # 如果链表是空的,则什么都不做
return

    if self.__head.data == value:  # 如果链表的头Node节点就是指定删除的Node节点
        self.__head = self.__head.next

    pro = self.__head
    node = self.__head.next
    not_found = False
    while node.data != value:
        if node.next == None:  # 如果已经到链表的最后一个节点,则表明该链表中没有找到执行Value值的Node节点
            not_found == True
            break
        else:
            pro = node
            node = node.next
    if not_found == False:
        pro.next = node.next

`

python/06_linkedlist/singlyLinkedList.py delete_by_value方法有内存回收问题吗?

按照个人理解:
程序当值相等时只下移current指针,下一个循环且值不相等时,将prev指针的next指针指向current指针,并下移prev指针。
这样刚好单向跳过了需要删除的节点。也就是链里不会再遍历到删除节点。
但是删除的节点的next指针其实还是指在链上,本身节点也没有=None.
这样会不会造成垃圾无法回收?

singly_linked_list.py

def delete_by_value(self, value:int):
    if not self._head or not value:
        return
    fake_head = Node(-1)
    fake_head._next = self._head
    prev, current = fake_head, self._head
    
    while current:
        if current.data != value:
            prev._next = current
            prev = prev._next
        current = current._next
    if prev._next:
        prev._next = None
    self._head = fake_head._next  # in case head.data == value

php版插入排序有问题?

换个数据,示例的排序会出错

function insertSort(&$data)
{
    $length = count($data);

    for ($i = 1; $i < $length; $i++) {
        $temp = $data[$i];
        for ($j = $i; $j > 0; $j--) {
            if ($data[$j - 1] > $temp) {
                $data[$j] = $data[$j - 1];
            } else {
                break;
            }
        }
        $data[$j] = $temp;
    }
}

$arr = [4, 5, 6, 1, 3, 2];
insertSort($arr);
print_r($arr);

#90 修改错了insert和print_all

  1. insert
    #90 把insert改成了如果index大于现有的元素数量,但是array本身还有空间的话,会插入到末尾。这样会造成:
a = MyArray(6)   # 生成一个capacity为6的array
for i in range(5):
    a.insert_to_tail(i)

print(a)        #  现在a是 [0, 1, 2, 3, 4]

a.insert(100, 1000)    # 在index为100的地方插入1000

这里应该返回False,插入不成功,但现在的修改导致a变成了[0, 1, 2, 3, 4, 1000]

同样的道理,如果a现在是[0, 1, 2, 3, 4],接下来

a.insert(-1, 1000)     # 在倒数第一位插入1000

应该结果为[0, 1, 2, 3, 4, 1000],但现在的修改导致a变成了[1000, 0, 1, 2, 3, 4]

  1. print_all
    print("{num}", end=" ")应该是print(f"{num}", end=" ").

  2. delete
    delete现在用新的slice去覆盖,这就导致如果对array进行不断删除,再不断添加,等等,它可能不是O(1)。

06_linkedlist-SinglyLinked 可重复删除指定 value 的代码有问题

会报空指针,我改成这样子,应该还会有更好的方法 while (head != null && head.data == value) { head = head.next; } Node pNode = head; while (pNode != null && pNode.next != null) { if (pNode.next.data == value) { pNode.next = pNode.next.next; continue; } pNode = pNode.next; }

12章、go语言实现的快速排序有问题,无限循环

`func partition(arr []int, low int, high int) int {
pivot := arr[high]
i := low
for j := low; j < high; j++ {
if arr[j] < pivot {
arr[i], arr[j] = arr[j], arr[i]
i++
}
}
arr[i], arr[high] = arr[high], arr[i]
return i
}

quickSort(arr, start, pivot-1)`
修改以上,可以正确运行 。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.