链表

线性表的链式存储

心已入冬 提交于 2020-02-08 04:48:08
顺序存储结构的插入和删除需要移动大量元素,显然很浪费时间。如果用链表来创建线性表,让两个元素之间能够有联系,找到一个元素就能知道它的下一个元素的位置在哪里。 创建一个线性表的链表 typedef struct Node { int data; //数据域 struct Node *next; //指针域 }Node; typedef struct Node *LinkList; 链表由数据域和指针域组成。 线性表-单链表 单链表的插入 操作如下: 代码如下: int Linkinsert(LinList *L,int i,int e) { int j; LinkList p,s; //p为线性表L,s为新建的结点,数据域放入要插入的元素 p=*L; j=1; while(p&&j<i) //找到第i-1个节点 { p=p->next; ++j; } if(!p||j>i) { return ERROR; } s=(LinkList)malloc(sizeof(Node)); //为新节点申请空间 s->data=e; s->next=p->next; p->next=s; return OK; } 单链表的删除 操作如下: 代码如下 int LinkDelet(LinkList *L,int i,int e) { int j; LinkList p,s; /

【LeetCode】相交链表

ぐ巨炮叔叔 提交于 2020-02-08 02:49:13
题目描述 编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。 示例1: 示例2: 示例3: 注意: 1、如果两个链表没有交点,返回 null。 2、在返回结果后,两个链表仍须保持原有的结构。 3、可假定整个链表结构中没有循环。 4、程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。 完整代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode * getIntersectionNode ( struct ListNode * headA , struct ListNode * headB ) { int lenA = 0 ; int lenB = 0 ; struct ListNode * curA = headA ; struct ListNode * curB = headB ; while ( curA && curA -> next != NULL ) { lenA ++ ; curA = curA -> next ; } while ( curB && curB -> next != NULL ) { lenB ++ ; curB =

[LeetCode] 160. 相交链表

假装没事ソ 提交于 2020-02-08 01:13:26
1 题目描述 编写一个程序,找到两个单链表相交的起始节点。 如下面的两个链表: 在节点 c1 开始相交。 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 示例 3: 输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 输出:null 输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。 解释:这两个链表不相交,因此返回 null。 注意: 如果两个链表没有交点,返回 null. 在返回结果后,两个链表仍须保持原有的结构。 可假定整个链表结构中没有循环。 程序尽量满足 O(n)

【LeetCode】环形链表II

夙愿已清 提交于 2020-02-08 00:55:02
题目描述 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 **说明:**不允许修改给定的链表。 示例1: 示例2: 示例3: 解题思路 可以分为两个部分。首先判断出该链表是否有环。其次,用相遇结点来找到环的入口。 第一部分:设置快、慢两个指针,慢指针走一步,快指针走两步。如果链表中不存在环,快指针最终会走到尾部,此时返回NULL;若链表中存在环,快指针最终会追上慢指针,返回相遇结点。 第二部分:设置meet指针指向根据第一部分找出的相遇结点,然后每次将meet指针和head指针往前移动一步,直到它们相遇,它们相遇的点就是环的入口,返回这个节点。 完整代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ //判断链表是否有环 struct ListNode * hasCycle ( struct ListNode * head ) { struct ListNode * fast = head ; struct ListNode * slow =

剑指offer 复杂链表的复制

余生颓废 提交于 2020-02-08 00:00:18
题目描述 原题链接 算法 (线性扫描) O ( n ) O(n) O ( n ) 复制每个节点,如:复制节点A得到A’,将A’插入节点A后面 遍历链表,A’->random = A->random->next; 将链表拆分成原链表和复制后的链表 时间复杂度是 O ( n ) O(n) O ( n ) ,空间复杂度是 O ( n ) O(n) O ( n ) 参考示意图 代码 /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public : RandomListNode * Clone ( RandomListNode * pHead ) { if ( ! pHead ) return NULL ; // A->A'->B->B'->C->C'->NULL // 复制每个结点,如复制结点A得到A',将结点A'插到结点A后面 auto p = pHead ; while ( p ) { auto q = new RandomListNode ( p - > label ) ; // 插入A' q - > next

C++链表

和自甴很熟 提交于 2020-02-07 23:58:22
C++链表 主要内容来源于 CSDN博客 并加以整理。 链表的理解 你现在有一个小纸条,上面写着一个抽屉的地址,那个抽屉里有一些你需要的东西,和一个新的写着地址的小纸条,这个小纸条又指向了一个新的抽屉。 需要的头文件 # include <iostream> # include <cstdlib> # include <ctime> //随机链表才需要 # include <string> using namespace std ; 建立链表节点结构 建立一个简单的链表结构可以写为: struct listpoint { int data ; listpoint * next ; } ; 这里的 int data 是一个int数字,也就是我们的数据;而 listnode*next 是指向下一个链表节点的指针。可以有指向下一个节点的指针的话,自然也可以有指向上一个节点的指针 listnode *last ; struct listpoint { int data ; listpoint * next ; listpoint * last ; } ; 同样的,在一个指针节点上不仅仅可以放一个数,也可以是一个结构体,比如这里定义了一个结构体 mydata 用于存放一个学生的学号,姓名,性别信息: struct mydata { int number ; char name [ 20 ]

114. 二叉树展开为链表

筅森魡賤 提交于 2020-02-07 16:17:12
1 题目 链接: 二叉树展开为链表 2 Python 2.1 方法一:递归 思想:左子树接到根节点的右子树位置,右子树接到左子树的右子树位置 从二叉树的左下角往右上角逐个操作 # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class Solution : def flatten ( self , root : TreeNode ) - > None : """ Do not return anything, modify root in-place instead. """ # 出口函数 if not root : return None ; # 递归过程 self . flatten ( root . right ) ; self . flatten ( root . left ) ; if root . left : right = root . right ; root . right = root . left ; root . left = None ; # 找到左子树(已经接到了根节点的右子树位置)最下层的右子树 while root . right

基数排序(radixSort)

丶灬走出姿态 提交于 2020-02-07 15:51:39
基数排序 基数排序算法的思想很有趣,他不依靠直接比较元素排序。而是采用分配式排序,单独处理元素的每一位。从最高位向最低位处理 称为:最高位优先(MSD)反之称为:最低位优先(LSD)。基数排序也称为桶排序。下面以最低位优先为例。 原理 准备10个容器,编号0-9,对应数字0-9。 容器是有序的(按添加顺序) 然后按待排序元素的 某一位的 数字 (比如:个位/十位/白位)将其存放到对应容器中(数字相同,如: 个位是数字1时, 就把这个元素放在1号桶),所有元素这样处理完后, 再从0号容器开始依次到9号容器, 将其中的元素顺序取出。所以容器内的元素收集合并 复制回原数组 ,然后再从下一位开始…(比如个位处理完后, 再处理十位/百位....最高位) 这里假设数组元素都是3位数。从个位开始,将数组中的元素按个位数字放入对应的桶中,再从桶中顺序取出到数组,这是数组按个位数字有序排列,再以相同的逻辑处理十位和百位。最后数组中就是有序的了 这里的排序原理是:将元素按位排序, 但是优先级不同, 做高位优先级高, 然后是次高位...。这样考虑:一组元素按最高位排序,那么在不考虑其他位的情况下,这组元素是有序的。再考虑低位,当个位排序好后,在排序十位,这时对十位的排序影响个位了吗?并没有。这就是优先级(权重)的问题, 十位对数字大小的影响显然比个位高。 示例代码1 示例算法测试效率并不高

集合各实现类的底层实现原理

回眸只為那壹抹淺笑 提交于 2020-02-07 15:46:26
转载自:http://blog.csdn.net/qq_25868207/article/details/55259978 ;##ArrayList实现原理要点概括 参考文献: http://zhangshixi.iteye.com/blog/674856l ArrayList是List接口的可变数组非同步实现,并允许包括null在内的所有元素。 底层使用数组实现 该集合是可变长度数组,数组扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量增长大约是其容量的1.5倍,这种操作的代价很高。 采用了Fail-Fast机制,面对并发的修改时,迭代器很快就会完全失败,而不是冒着在将来某个不确定时间发生任意不确定行为的风险 LinkedList实现原理要点概括 参考文献: http://www.cnblogs.com/ITtangtang/p/3948610.htmll LinkedList是List接口的双向链表非同步实现,并允许包括null在内的所有元素。 底层的数据结构是基于双向链表的,该数据结构我们称为节点 双向链表节点对应的类Node的实例,Node中包含成员变量:prev,next,item。其中,prev是该节点的上一个节点,next是该节点的下一个节点,item是该节点所包含的值。 HashMap实现原理要点概括 参考文献: http://zhangshixi