单链表

顺序表之链式存储(单链表) 基本操作c++实现

痴心易碎 提交于 2019-11-29 06:26:27
//链式存储之单链表 #include<iostream> using namespace std; typedef int elemtype;//此处int可替换成别的数据类型 //创建节点 typedef struct node { elemtype data; //数据域 struct node *next; //指针域 }node,*listnode; /* 此处需要注意 1. listnode ln; ln是单链表的头指针 **节点变量** 2. node *p; *p是指向单链表中某个节点的指针 **指针变量** */ //1.单链表的初始化 /* 步骤: 1.生成新节点作为头节点,用头指针l指向头节点 2.头节点的指针域=null */ bool newlist(listnode &l) { l=new node; l->next=NULL;//NULL 需要全部大写 return true; } //单链表的取值 /* 步骤: 1.指针p指向首元节点,计数器j=1;(首元节点是第一个存储数据的节点) 2.从首元节点开始顺着*next向下访问 3.只要p!=NULL且未到达第i个位置(j<i)就循环执行以下操作 a.p指向下一个节点 b.j++ 4.退出循环时,如果指针p为空||j>i,说明i的值不合法,返回false 5.如果j==i,则返回e=p->data */

单链表调整

孤街浪徒 提交于 2019-11-28 20:35:40
单链表调整【C语言】 题目: 单链表 (a1,a2,a3,a4,…,an) 要求将该单链表调整成如下结构 (an,an-2,…,a4,a2,a1,a3, …,an-3,an-1) 时间复杂度为O(n) 空间复杂度为O(1) 代码: /*8*/ # include <stdio.h> # include <stdlib.h> # define elemtype int int num = 0 ; typedef struct Node { elemtype data ; struct Node * next ; } Node ; typedef Node * Linklist ; void Initlist ( Linklist * L ) { * L = ( Linklist ) malloc ( sizeof ( Node ) ) ; ( * L ) -> next = NULL ; } void CreateFromTail ( Linklist L ) { int i = 0 ; Node * r = L , * s ; elemtype e ; while ( i != num ) { scanf ( "%d" , & e ) ; s = ( Node * ) malloc ( sizeof ( Node ) ) ; s -> data = e ; r -> next =

单链表的C语言实现

被刻印的时光 ゝ 提交于 2019-11-28 20:13:11
目录 整表创建 头插法 尾插法 整表删除 插入单个节点 删除单个节点 头插法 Link tcreatelist() { int value,len; Link head = (Link)malloc(sizeof(link));//先创建头结点,头结点的数据域没有值 head->next = NULL; //使头结点下一个节点指向NULL printf("input the node you want!!\n"); scanf("%d",&len); //输入要输入链表的长度 for(int i=0;i<len;i++) { scanf("%d",&value); Link a = (Link)malloc(sizeof(link));//创建新结点 a->data=value; //将输入值赋给这个结点的数据域 a->next=head->next; //让这个新结点的下一个结点指向头结点的下一个结点 head->next=a; //让头结点的下一个结点指向这个新结点 } return head; //返回链表头 } 尾插法 Link wcreatelist() { int value,len; Link head = (Link)malloc(sizeof(link)); //表示头结点 Link tail = head; //定义一个尾指针,这个尾指针也指向这个头结点

树的存储、森林的存储

混江龙づ霸主 提交于 2019-11-27 16:53:10
树的存储:   二叉树的存储:     1. 连续存储(顺序存储) 【完全二叉树】,以数组实现       优点:         查找某个节点的父节点和子节点(包括判断有没有子节点和父节点)       缺点:         耗用内存空间过大     2. 链式存储:       一个节点包含三个部分:左子节点地址、数据域、右子节点地址       优点:耗内存小     3. 一般树的存储:       由于计算机的内存是线性的,而树是非线性的。若在计算机里只存树的有效节点,便不能查找某个节点的子节点和父节点(或者说整个树的逻辑存储无法知晓),所以必须要先转化成完全二叉树,把垃圾节点补上。 绿色的是普通树,蓝色的是转为满二叉树,黄色的是去掉了底层连续的叶子节点,即成了完全二叉树    双亲表示法: 由于树中的每个结点都有唯一的一个双亲结点,所以可用一组连续的存储空间(一维数组)存储树中的各个结点,数组中的一个元素表示树中的一个结点,每个结点含 两个域 ,数据域存放结点本身信息,双亲域指示本结点的双亲结点在数组中位置(下标)。方便查询某结点的父结点    孩子表示法: 将树中的每个结点的孩子结点排列成一个线性表,用链表存储起来。对于含有 n 个结点的树来说,就会有 n 个单链表,将 n 个单链表的头指针存储在一个线性表中,这样的表示方法就是孩子表示法。如果结点没有孩子

大话数据结构读后感(一)线性表栈与队列

℡╲_俬逩灬. 提交于 2019-11-27 06:16:13
3.2 线性表的定义 3.3 线性表的抽象数据类型行:创建,销毁,增删改查等等操作 3.4 线性表之顺序存储 :顺序表 3.5 顺序表的插入和删除:相当于数组的插入和删除;然后把当前length +(-) 1;   顺序表的优点:无须为表示表中的元素之间的逻辑关系而添加额外的存储空间;可以快速地访问存取表中的任意位置子的元素;   缺点:插入和删除操作需要移动大量的元素;当线性表长度变化较大时,难以确定存储空间的容量;造成存储空间的碎片; 3.6 线性表的链式存储结构:链表 解决了顺序表的增删需要移动大量元素的问题; 3.7 单链表的读取:next指针遍历; 3.8 单链表的插入和删除:插入s : s->next=p->next; p->next=s; 删除s:s=q; p->next=s->next; free(s); 3.9 单链表的整表创建:(插入) 头插和尾插:尾插最后指向NULL; 3.10 单链表的整表删除:挨个删除 : p=head->next; while(p!=NULL) { q=p->next; free(p) ; p=q; } 3.11 单链表结构与顺序结构存储结构优缺点: 存储分配方式:顺序表存储单元连续,线性表任意存储位置; 时间性能:顺序表方便查找;单链表适合插入和删除; 空间性能:顺序表需预先分配存储空间,分大了浪费,分小了容易上溢;

py002 - 单链表python代码实现

删除回忆录丶 提交于 2019-11-27 05:34:20
Code: class Node ( object ) : """结点""" def __init__ ( self , elem ) : self . elem = elem self . next = None class SingleLinklist ( object ) : """单链表""" def __init__ ( self , node = None ) : self . __head = node def is_empty ( self ) : """判断单链表是否为空""" return self . __head == None def length ( self ) : """单链表长度""" cur = self . __head # 设置游标cur count = 0 # 设置计数器 while cur != None : count += 1 cur = cur . next return count def travel ( self ) : """遍历单链表""" cur = self . __head # 设置游标cur while cur != None : print ( cur . elem , end = " " ) cur = cur . next print ( ) def add ( self , elem ) : ""

54-图的邻接表存储结构

筅森魡賤 提交于 2019-11-26 22:22:35
  我们知道图的存储结构有邻接矩阵存储方法和邻接表存储方法,而对于邻接矩阵我们已经学习过了,本篇将主要介绍图的邻接表存储结构。 图1-图的邻接表存储结构 1. 邻接表存储带权有向图 图2-邻接表存储有向图    邻接表存储方法是对图中每个顶点i建立一个单链表,将顶点i的所有邻接点链接起来,然后再给每个单链表上附设一个表头节点(表示顶点信息),将所有表头节点构成一个数组(顺序表),下标为i的元素表示顶点i的表头节点,因此不难看出单链表中的每个节点代表着一条边,我们称之为边节点 。 2. 邻接表的存储结构   从邻接表存储方法我们可知,图的邻接表存储方法是一种 顺序分配和链式分配 相结合的存储方法。而且邻接表中有两类节点:表头节点和单链表中的边节点。   如图2所示,在表头节点中的data域表示每个顶点的信息,firstarc域用于指向单链表的第一个边节点(即相关联的邻接点),而单链表中的每个边节点又包括了adjvex域,nextar域,info域。   adjvex域用于存储某顶点的邻接点,而nextar域则用于指向单链表中的下一个边节点,而info域则用于存储边节点信息,如权值。 由以上这些信息,我们可以定义邻接表存储结构,如下所示: typedef struct ANode { int adjvex; //记录某顶点的邻接点 struct ANode *nextarc; /

队列(单链表)

孤者浪人 提交于 2019-11-26 17:54:57
头文件 #pragma once //利用带头节点的单链表实现队列,队头为第一个数据节点 typedef struct Node { int data; struct Node *next; }Node;//数据节点 typedef struct HNode { struct Node *front;//队头指针 struct Node *rear;//队尾指针 }HNode,*PLQueue;//头节点 void InitQueue(PLQueue pl); //入队 bool Push(PLQueue pl,int val); //获取队头的值,但不删除 bool GetTop(PLQueue pl,int *rtval); //获取队头的值,且删除 bool Pop(PLQueue pl,int *rtval); bool IsEmpty(PLQueue pl); void Destroy(PLQueue pl); cpp文件 #include <stdio.h> #include <assert.h> #include <stdlib.h> #include "lqueue.h" //利用带头节点的单链表实现队列,队头为第一个数据节点 void InitQueue(PLQueue pl) { assert(pl != NULL); pl->front = NULL; pl-

对HashMap的思考及手写实现

这一生的挚爱 提交于 2019-11-26 02:41:56
前言 HashMap是Java中常用的集合,而且HashMap的一些思想,对于我们平时解决业务上的一些问题,在思路上有帮助,基于此,本篇博客将分析HashMap底层设计思想,并手写一个迷你版的HashMap! 对HashMap的思考 第一,如图所示,HashMap有3个要素:hash函数+数组+单链表 第二,对于hash函数而言,需要考虑些什么? 要快,对于给定的Key,要能够快速计算出在数组中的index。那么什么运算够快呢?显然是位运算! 要均匀分布,要较少碰撞。说白了,我们希望通过hash函数,让数据均匀分布在数组中,不希望大量数据发生碰撞,导致链表过长。那么怎么办到呢?也是利用位运算,通过对数据的二进制的位进行移动,让hash函数得到的数据散列开来,从而减低了碰撞的概率。 如果发生了碰撞怎么办?上面的图其实已经说明了JDK的HashMap是如何处理hash冲突的,就是通过单链表解决的。那么除了这个方法,还有其他思路么?比如说,如果发生冲突,那么记下这个冲突的位置为index,然后在加上固定步长,即index+step,找到这个位置,看一下是否仍然冲突,如果继续冲突,那么按照这个思路,继续加上固定步长。其实这就是所谓的线性探测来解决Hash冲突的方法! 通过写一个迷你版的HashMap来深刻理解 定义接口 定义一个接口,对外暴露快速存取的方法。