单链表

旋转单链表

心已入冬 提交于 2020-03-20 00:20:36
3 月,跳不动了?>>> 原题   Given a list, rotate the list to the right by k places, where k is non-negative.   For example:   Given 1->2->3->4->5->NULL and k = 2 ,   return 4->5->1->2->3->NULL . 题目大意   向右旋转一个单链表,旋转k个位置,k非负数。 解题思路   用一个辅助root结点连接到链表头,先找到要移动的第一个结点的前驱prev,再将prev后的所有结点接到root后面,再将组成一个旋转后的单链表。 代码实现 链表结点类 public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } 1 2 3 4 5 1 2 3 4 5 算法 实现类 public class Solution { public ListNode rotateRight(ListNode head, int n) { if (head == null || n < 1) { return head; } ListNode root = new ListNode(0); root.next = head; ListNode p =

单链表及其基本运算和小应用

十年热恋 提交于 2020-03-12 02:34:43
单链表的c语言定义 typedef struct Node { ElemType data ; /*数据域*/ struct Node * next ; /*指针域*/ } Node , * LinkLIst ; /*给node起两个别名,这两个别名等效*/ LinkLIst L ; /*L为单链表的头指针,也称为单链表L*/ LinkList 与 Node*同为结构指针类斜体样式型,这两种类型是等价的。 通常我们习惯上用LinkList说明指针变量,强调它是某个单链表的头指针变量,用 Node*来定义指向单链表中节点的指针。 单链表的基本运算 一、求带头节点单链表的长度 int listlength ( linklist L ) { node * p ; p = -> next ; j = 0 ; /*用来存放单链表的长度*/ while ( p != NULL ) { p = p -> next ; j ++ ; } return j ; } 二、建表 1.建立空表 InitList ( linklist * L ) /*建立空表*/ { L = ( linklist ) malloc ( sizeof ( node ) ) ; L -> next = NULL ; } 2.头插法建表 linklist creatfromhead ( linklist l ) { node *

有序单链表删除重复元素

左心房为你撑大大i 提交于 2020-03-10 06:45:51
前言 本文从有序单链表入手,主要思想是定义三个结构类型指针来解决有序单链表删除重复元素的问题。 图示 其中 flag 作为标杆值, p 去寻找相同的值。若相同则 p 移动到下一个,同时定义结构指针 q 指向其多余的结点以释放内存;若不同则 flag 和 p 都向下移动。( PS :单链表有序且已有数据储存) 代码 node结构(举例说明) typedef struct _Node { int data ; //数据域 struct _Node * next ; //指针域 } node ; listDelDuplicates()函数 void listDelDuplicates ( node * & head ) { //定义变量 node * flag = head ; //flag作为标杆值 node * p = head - > next ; //P移动寻找相同值 while ( p ) { if ( flag - > data == p - > data ) //若flag的值和p的值相同时 { node * q = p ; //定义一个q去指向p,目的是为了释放内存 flag - > next = p - > next ; //flag的next指向p的next p = p - > next ; //p指向下一个结点 delete q ; //释放q所指的结点 }

链表结构体实现(单链表,循环链表)

徘徊边缘 提交于 2020-03-08 09:38:16
// 无表头节点的单链表 #include <iostream> #include <cstdio> #include <malloc.h> using namespace std; typedef char ListData; typedef struct node{ ListData data; struct node* link; }ListNode; typedef ListNode* LinkList; LinkList first; int insert(LinkList& first, ListData x, int i) { ListNode* preNode = first; int cnt = 0; while(preNode != NULL && cnt < i - 1) { preNode = preNode -> link; cnt ++; } if(preNode == NULL && first != NULL){ puts("无效的插入!"); return false; } ListNode* newnode = listNode* malloc(sizeof(node)); newnode->data = x; if(i == 1 || first == NULL) !!!!为什么不是 i == 0!!! { newnode->link =

快慢指针

丶灬走出姿态 提交于 2020-02-29 09:23:45
所谓快慢指针中的快慢指的是指针向前移动的步长,每次移动的步长较大即为快,步长较小即为慢,常用的快慢指针一般是在单链表中让快指针每次向前移动2,慢指针则每次向前移动1。 快慢指针在提高查找性能方面的作用还是比较可观的,如以下应用: (1)如何快速找出未知长度单链表的中间节点? 普通方法:先遍历一遍单链表确定其长度L后,再从头节点出发循环L/2次即可查找到单链表的中间节点。该问题如果采用普通的方法虽然简单,但是查找效率太低。 快慢指针: 设置两个指针*fast、*slow都指向单链表的头节点,其中*fast的移动速度是*slow的2倍,当*fast指向末尾节点的时候,slow正好就在中间了,可以大大提高查找的效率。 当然,此时算法 还要考虑链表结点个数的奇偶数因素,当快指针移动x次后到达表尾(1+2x),说明链表有奇数个结点,直接返回慢指针指向的数据即可。如果快指针是倒数第二个结点,说明链表结点个数是偶数,这时 可以 实际情况 返回上中位数或下中位数或(上中位数+下中位数)的一半。 1 while (fast&&slow) 2 { 3   if (fast->next==NULL) 4    return slow ->data; 5   else if (fast->next!= NULL && fast->next->next== NULL) 6    return (slow -

单链表常见题目(头插法理解)

为君一笑 提交于 2020-02-28 13:39:10
我们用上一篇中的代码接着实现,上一篇点击 单链表的简单介绍和实现增删改查 1 求有效节点的个数 /* * 求单链表有效长度(如果是带头结点的链表,需求不统计头节点) */ public int getLength ( ) { if ( head . next == null ) { //空链表 return 0 ; } int length = 0 ; //定义一个辅助的变量, 这里我们没有统计头节点 HeroNode cur = head . next ; while ( cur != null ) { length ++ ; cur = cur . next ; } return length ; } 2 查找单链表倒数第k个结点 这里我们需要用到上面的有效节点个数的方法。 思路 1. 编写一个方法,接收head节点,同时接收一个index 2. index 表示是倒数第index个节点 3. 用上面的 getLength()方法,得到链表的有效总长度size 4. 得到size 后,我们从链表的第一个开始遍历 (size-index)个,就可以得到 5. 如果找到了,则返回该节点,否则返回nulll public HeroNode getBackKey ( int indax ) { //判断如果链表为空,返回null if ( head . next == null ) {

数据结构之单链表-c语言实现

丶灬走出姿态 提交于 2020-02-27 05:53:23
文章来源: http://blog.seclibs.com/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84%e4%b9%8b%e5%8d%95%e9%93%be%e8%a1%a8-c%e8%af%ad%e8%a8%80%e5%ae%9e%e7%8e%b0/ 常用的链表有单链表、双向链表和循环链表,这次只完成了单链表的c语言实现,在写代码中所遇到的问题在代码注释中也都有标注,在实现上最关键的还是对整体结构的理解,只有对整体结构有一定的了解,才能在具体的代码实现中少走很多的弯路,在具体的代码实现过程中,要着重关注每一个变量的内容和具体的含义,只有搞清楚了这一点才能在实现的时候不出现一些莫名其妙的问题。 比如在这次实现中,就碰到了在插入初始插入数据的时候,输出的内容一直与插入时相反,也就是说,起初预想的是每次插入数据都是在最后一位进行插入,而实际情况是从开头进行插入的,在仔细研究完代码后,发现了问题所在 我们在第一次插入数据的时候,情况是这样的 但是如果再继续往后面插入的时候,由于list所指的内存地址并没有改变,所以插入的情况是这样的 就造成了输出与输入呈倒序的方式,所以只需要将list所指向的内存地址进行变化就可以了,修改后的代码如下 所以对每个变量所代表的含义要特别清楚才能在代码实现的时候更加的清晰。 整体代码如下,如果需要下载代码请移步到文末 代码:

写给自己看的单链表(1):基本操作

旧巷老猫 提交于 2020-02-24 23:02:14
搬运自我的CSDN https://blog.csdn.net/u013213111/article/details/88382961 !!!Attention:以下操作中的单链表均带有头结点!!! 1.定义 定义一个eletype,便于更改元素的类型。node结构体有两个成员,一个是数据成员,一个是指向下一个节点的指针成员。给node结构体起个别名Lnode,这样就可以直接定义Lnode型变量,无需用struct node这么长的名字。 1 typedef int eletype; 2 3 typedef struct node 4 { 5 eletype data; 6 struct node *next; 7 }Lnode; 2.创建一个有n个元素的单链表 函数的返回值应该是表头(指针),这样才能够使用所创建的单链表。所以肯定要先创建Lnode *head。创建新的元素要用到malloc函数分配内存。 1 Lnode *CreateList(int n) //Create a single linkedlist with n elements 2 { 3 Lnode *head, *current, *s; 4 head = (Lnode*)malloc(sizeof(Lnode)); 5 current = head; 6 for (int i = 0; i < n; i+

哈希表中的查找

非 Y 不嫁゛ 提交于 2020-02-23 10:24:12
基本概念 哈希表 ( hash table ):又称散列表,其基本思路是,设要存储的元素个数是n,设置一个长度为m的连续存储单元,以每个元素的关键字作为自变量,通过哈希函数(h(k))把k映射到一个内存单元,并把该元素存在这个内存单元中,把像这样构造的线性表存储结构称为哈希表。 哈希冲突 ( hash collisions ):在构建哈希表时,出现两个不同关键词对应相同的哈希值,这种现象称作哈希冲突。 装填因子 ( loading factor ) : 设哈希表空间大小为n,填入表中元素个数为m,则$α=/frac{m}{n}$为哈希表的装填因子。 哈希查找两项基本工作: 计算位置:构造哈希函数确定关键词的位置 解决冲突:应用某种策略解决多个关键词位置相同的问题 这种查找的时间复杂度几乎是常量O(1),即查找时间与问题规模无关。 哈希函数的构造 一个好的哈希函数: 计算简单,以便提高转换速度 关键词对应地空间分布均匀,以尽量减少冲突 直接定址法 是以关键字k加上某个常量c作为哈希地址的方法,其哈希函数为:h(k)=k+c 特点:哈希函数计算简单。当关键字分布基本连续时,可以用直接定址法;否则,将造成内存单元大量浪费 除留余数法 是用关键字k除以整数p所得的余数作为哈希地址,表示为h(k)=k mod p 特点:计算比较简单,适用范围广,是最经常使用的一种哈希函数。