单链表头插法和尾插法原理及代码

单链表头插法和尾插法原理及代码
单链表头插法和尾插法原理及代码

单链表头插法和尾插法原理及代码

排列组合问题之捆绑法_插空法和插板法

“相邻问题”捆绑法,即在解决对于某几个元素要求相邻的问题时,先将其“捆绑”后整体考虑,也就是将相邻元素视作“一个”大元素进行排序,然后再考虑大元素内部各元素间排列顺序的解题策略。 例1.若有A、B、C、D、E五个人排队,要求A和B两个人必须站在相邻位置,则有多少排队方法? 【解析】:题目要求A和B两个人必须排在一起,首先将A和B两个人“捆绑”,视其为“一个人”,也即对“A,B”、C、D、E“四个人”进行排列,有种排法。又因为捆绑在一起的A、B两人也要排序,有种排法。根据分步乘法原理,总的排法有种。 例2.有8本不同的书,其中数学书3本,外语书2本,其它学科书3本。若将这些书排成一列放在书架上,让数学书排在一起,外语书也恰好排在一起的排法共有多少种? 【解析】:把3本数学书“捆绑”在一起看成一本大书,2本外语书也“捆绑”在一起看成一本大书,与其它3本书一起看作5个元素,共有种排法;又3本数学书有种排法,2本外语书有种排法;根据分步乘法原理共有排法种。 【王永恒提示】:运用捆绑法解决排列组合问题时,一定要注意“捆绑”起来的大元素内部的顺序问题。解题过程是“先捆绑,再排列”。 “不邻问题”插空法,即在解决对于某几个元素要求不相邻的问题时,先将其它元素排好,再将指定的不相邻的元素插入已排好元素的间隙或两端位置,从而将问题解决的策略。

例3.若有A、B、C、D、E五个人排队,要求A和B两个人必须不站在一起,则有多少排队方法? 【解析】:题目要求A和B两个人必须隔开。首先将C、D、E三个人排列,有种排法;若排成D C E,则D、C、E“中间”和“两端”共有四个空位置,也即是:︺ D ︺ C ︺ E ︺,此时可将A、B两人插到四个空位置中的任意两个位置,有种插法。由乘法原理,共有排队方法:。 例4.在一张节目单中原有6个节目,若保持这些节目相对顺序不变,再添加进去3个节目,则所有不同的添加方法共有多少种? 【解析】:直接解答较为麻烦,可根据插空法去解题,故可先用一个节目去插7个空位(原来的6个节目排好后,中间和两端共有7个空位),有种方法;再用另一个节目去插8个空位,有种方法;用最后一个节目去插9个空位,有方法,由乘法原理得:所有不同的添加方法为=504种。 例4.一条马路上有编号为1、2、……、9的九盏路灯,为了节约用电,可以把其中的三盏关掉,但不能同时关掉相邻的两盏或三盏,则所有不同的关灯方法有多少种? 【解析】:若直接解答须分类讨论,情况较复杂。故可把六盏亮着的灯看作六个元素,然后用不亮的三盏灯去插7个空位,共有种方法(请您想想为什么不是),因此所有不同的关灯方法有种。 【王永恒提示】:运用插空法解决排列组合问题时,一定要注意插空位置包括先排好元素“中间空位”和“两端空位”。解题过程是“先排列,再插空”。 练习:一张节目表上原有3个节目,如果保持这3个节目的相对顺序不变,再添加进去2个新节目,有多少种安排方法?(国考2008-57)

头插法建立单链表

#include #include typedefstruct node { int data; struct node *next; }lnode,*linklist; \*定义头结点的函数*\ linklistInitlist_l(); \*定义头插法的函数*\ linklistCreatelist_f(linklistl,int n); \*定义输出链表数据的函数*\ voidPrintlist(linklist); \*主函数*\ int main(void) { inti,s,n; linklist l; l=Initlist_l(); printf("Please input number of datas:\n"); scanf("%d",&n); Createlist_f(l,n); Printlist(l); return 0; } linklistInitlist_l() { linklist l; l=(linklist)malloc(sizeof(lnode)); l->next=0; return l; } linklistCreatelist_f(linklistl,int n) { int i; linklist p; for(i=0;idata); p->next=l->next; l->next=p; }

return l; } voidPrintlist(linklist l) { linklist p; p=l->next; while(p) { printf("%d\t",p->data); p=p->next; } printf("\n"); }

排列组合问题之捆绑法-插空法和插板法

行测答题技巧:排列组合问题之捆绑法,插空法和插板法 “相邻问题”捆绑法,即在解决对于某几个元素要求相邻的问题时,先将其“捆绑”后整体考虑,也就是将相邻元素视作“一个”大元素进行排序,然后再 考虑大元素内部各元素间排列顺序的解题策略。 例1 ?若有A、B、C、D E五个人排队,要求A和B两个人必须站在相邻位置,则有多少排队方法 【解析】:题目要求A和B两个人必须排在一起,首先将A和B两个人“捆绑”,视其为“一个人”,也即对“ A,B”、C D E “四个人”进行排列,有■< 种排法。又因为捆绑在一起的A、B两人也要排序,有I种排法。根据分步乘法原理,总的排法有I -种 例2.有8本不同的书,其中数学书3本,外语书2本,其它学科书3本。若 将这些书排成一列放在书架上,让数学书排在一起,外语书也恰好排在一起的排法 共有多少种 【解析】:把3本数学书“捆绑”在一起看成一本大书,2本外语书也“捆绑”在一起看成一本大书,与其它3本书一起看作5个元素,共有丄种排法;又3 本数学书有丄种排法,2本外语书有雹种排法;根据分步乘法原理共有排法.<■'I - -- I 种。 【王永恒提示】:运用捆绑法解决排列组合问题时,一定要注意“捆绑” 起来的大元素内部的顺序问题。解题过程是“先捆绑,再排列”。 “不邻问题”插空法,即在解决对于某几个元素要求不相邻的问题时,先将其它元素排好,再将指定的不相邻的元素插入已排好元素的间隙或两端位置,从而将 问题解决的策略。 例3.若有A、B、C、D E五个人排队,要求A和B两个人必须不站在一起,则有多少排队方法

【解析】:题目要求A和B两个人必须隔开。首先将C、D E三个人排列, 有「「种排法;若排成D C E,则D C E “中间”和“两端”共有四个空位置,也即是:?D C E ,此时可将 A B两人插到四个空位置中的任意两个位置,有q种插法。由乘法原理,共有排队方法:匚二 :-。 例4.在一张节目单中原有6个节目,若保持这些节目相对顺序不变,再添加进去3个节目,则所有不同的添加方法共有多少种 【解析】:直接解答较为麻烦,可根据插空法去解题,故可先用一个节目 去插7个空位(原来的6个节目排好后,中间和两端共有7个空位),有「种方法;再用另一个节目去插8个空位,有种方法;用最后一个节目去插9个空位,有」:.方法,由乘法原理得:所有不同的添加方法为匚-.,=504种。 例4.一条马路上有编号为1、2、……、9的九盏路灯,为了节约用电, 可以把其中的三盏关掉,但不能同时关掉相邻的两盏或三盏,则所有不同的关灯方法有多少种 【解析】:若直接解答须分类讨论,情况较复杂。故可把六盏亮着的灯看作六个元素,然后用不亮的三盏灯去插7个空位,共有'种方法(请您想想为什么不是八),因此所有不同的关灯方法有'_「种。 【王永恒提示】:运用插空法解决排列组合问题时,一定要注意插空位置包括先排好元素“中间空位”和“两端空位”。解题过程是“先排列,再插空”。 练习:一张节目表上原有3个节目,如果保持这3个节目的相对顺序不变,再添加进去2个新节目,有多少种安排方法(国考2008-57) A. 20 B . 12 C . 6 D . 4 插板法是用于解决“相同元素”分组问题,且要求每组均“非空”,即要求

C语言链表专题复习

链表专题复习 数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性。但数组也同样存在一些弊病。如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中针对不同问题有时需要3 0个元素大小的数组,有时需要5 0个数组元素的大小,难于统一。我们只能够根据可能的最大需求来定义数组,常常会造成一定存储空间的浪费。 我们希望构造动态的数组,随时可以调整数组的大小,以满足不同问题的需要。链表就是我们需要的动态数组。它是在程序的执行过程中根据需要有数据存储就向系统要求申请存储空间,决不构成对存储区的浪费。 链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表、循环链表、双向链表,下面只介绍单向链表。 7.4.1 单链表 图7 - 3是单链表的结构。 单链表有一个头节点h e a d,指向链表在内存的首地址。链表中的每一个节点的数据类型为结构体类型,节点有两个成员:整型成员(实际需要保存的数据)和指向下一个结构体类型节点的指针即下一个节点的地址(事实上,此单链表是用于存放整型数据的动态数组)。链表按此结构对各节点的访问需从链表的头找起,后续节点的地址由当前节点给出。无论在表中访问那一个节点,都需要从链表的头开始,顺序向后查找。链表的尾节点由于无后续节点,其指针域为空,写作为N U L L。 图7 - 3还给出这样一层含义,链表中的各节点在内存的存储地址不是连续的,其各节点的地址是在需要时向系统申请分配的,系统根据内存的当前情况,既可以连续分配地址,也可以跳跃式分配地址。 看一下链表节点的数据结构定义: struct node { int num; struct node *p; } ; 在链表节点的定义中,除一个整型的成员外,成员p是指向与节点类型完全相同的指针。 在链表节点的数据结构中,非常特殊的一点就是结构体内的指针域的数据类型使用了未定义成功的数据类型。这是在C中唯一规定可以先使用后定义的数据结构。 ?单链表的创建过程有以下几步: 1 ) 定义链表的数据结构。 2 ) 创建一个空表。 3 ) 利用m a l l o c ( )函数向系统申请分配一个节点。

数据结构--单链表的插入和删除

单链表的插入和删除实验日志 指导教师刘锐实验时间2010 年10 月11 日 学院数理专业数学与应用数学 班级学号姓名实验室S331-A 实验题目:单链表的插入和删除 实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。 实验要求:建立一个数据域定义为字符串的单链表,在链表中不允许有重复的字符串;根据输入的字符串,先找到相应的结点,后删除之。 实验主要步骤: 1、分析、理解程序(相关程序见附录) 。 2、调试程序,并设计输入字符串数据(如:aa, bb , cc , dd, ee,#),测试程序的如下功能: 不允许重复字符串的插入;根据输入的字符串,找到相应的结点并删除。 3、修改程序: (1)增加插入结点的功能。 (2)将建立链表的方法改为头插入法。 实验结果: 1、不允许重复字符串的插入功能结果如下:

3、删除和插入结点的功能如下:

心得体会: 通过这次实验我学会了单链表的建立和删除,基本了解了线性表的逻辑结构和链式存储结构,掌握了单链表的基本算法,使我受益匪浅。在调试程序的过程中,遇见了一系列的问题,后来在同学的帮助下,修改了几个语句后,终于把它给调试出来了。有时候一个标点符号的问题就可能导致程序无法运行。所以在分析调试程序的时候一定要仔细。 附加程序代码: 1、调试之后的程序如下(其中蓝色字体部分为修改过的): #include"stdio.h" #include"string.h" #include"stdlib.h" #include"ctype.h" typedef struct node //定义结点 { char data[10]; //结点的数据域为字符串 struct node *next; //结点的指针域 }ListNode; typedef ListNode * LinkList; // 自定义LinkList单链表类型 LinkList CreatListR1(); //函数,用尾插入法建立带头结点的单链表ListNode *LocateNode(); //函数,按值查找结点

单链表的基本操作

上机实验报告 学院:计算机与信息技术学院 专业:计算机科学与技术(师范)课程名称:数据结构 实验题目:单链表建立及操作 班级序号:师范1班 学号:201421012731 学生姓名:邓雪 指导教师:杨红颖 完成时间:2015年12月25号

一、实验目的: (1)动态地建立单链表; (2)掌握线性表的基本操作:求长度、插入、删除、查找在链式存储结构上的实现; (3)熟悉单链表的应用,明确单链表和顺序表的不同。 二、实验环境: Windows 8.1 Microsoft Visual c++ 6.0 三、实验内容及要求: 建立单链表,实现如下功能: 1、建立单链表并输出(头插法建立单链表); 2、求表长; 3、按位置查找 4、按值查找结点; 5、后插结点; 6、前插结点 7、删除结点; 四、概要设计: 1、通过循环,由键盘输入一串数据。创建并初始化一个单链表。 2、编写实现相关功能函数,完成子函数模块。 3、调用子函数,实现菜单调用功能,完成顺序表的相关操作。

五、代码: #include #include typedef char datatype; typedef struct node { datatype data; struct node *next; }linklist; linklist *head,*p; //头插法建立单链表 linklist *Creatlistf() { char ch; linklist *head,*s; head=NULL; ch=getchar(); printf("请输入顺序表元素(数据以$结束):\n"); while(ch!='$') { s=(linklist *)malloc(sizeof(linklist)); s->data=ch; s->next=head; head=s; ch=getchar(); } return head; } //求单链表的长度 void get_length(struct node *head) { struct node *p=head->next; int length=0;

单链表的建立及其基本操作的实现(完整程序)

#include "stdio.h"/*单链表方式的实现*/ #include "malloc.h" typedef char ElemType ; typedef struct LNode/*定义链表结点类型*/ { ElemType data ; struct LNode *next; }LNode,*LinkList;/*注意与前面定义方式的异同*/ /*建立链表,输入元素,头插法建立带头结点的单链表(逆序),输入0结束*/ LinkList CreateList_L(LinkList head) { ElemType temp; LinkList p; printf("请输入结点值(输入0结束)"); fflush(stdin); scanf("%c",&temp); while(temp!='0') { if(('A'<=temp&&temp<='Z')||('a'<=temp&&temp<='z')) { p=(LinkList)malloc(sizeof(LNode));/*生成新的结点*/ p->data=temp; p->next=head->next; head->next=p;/*在链表头部插入结点,即头插法*/ } printf("请输入结点值(输入0结束):"); fflush(stdin); scanf("%c",&temp); } return head; } /*顺序输出链表的内容*/ void ListPint_L(LinkList head) { LinkList p; int i=0; p=head->next; while(p!=NULL) { i++; printf("单链表第%d个元素是:",i);

单链表基本操作实验

实验2 链表的操作 实验容: 1)基础题:编写链表基本操作函数,链表带有头结点 (1)CreatList_h()//用头插法建立链表 (2)CreateList_t()//用尾插法建立链表 (3)InsertList()向链表的指定位置插入元素 (4)DeleteList()删除链表中指定元素值 (5)FindList()查找链表中的元素 (6)OutputList()输出链表中元素 2)提高题: (1)将一个头节点指针为heada的单链表A分解成两个单链表A和B,其头结点指针分别为heada和headb,使得A表中含有原单链表A中序号为奇数的元素,B表中含有原链表A中序号为偶数的元素,且保持原来的相对顺序。 (2)将一个单链表就地逆置。 即原表(a1,a2,。。。。。。 an),逆置后新表(an,an-1,。。。。。。。a1) /* 程序功能 :单链表基本功能操作 编程者 :天啸 日期 :2016-04-14 版本号 :3.0 */ #include #include typedef struct List { int data; struct List *next; }List; void CreatList_h(List *L) //头插法 { int i = 0; int n = 0; int goal; List *p; printf("请输入数据的个数:\n"); scanf("%d",&n); L -> next = NULL; for(i=0;i

{ printf("请输入第%d个数:\n",i+1); scanf("%d",&goal); p = (struct List*)malloc(sizeof(struct List)); p -> data = goal; p -> next = L->next; //将L指向的地址赋值给p; L -> next = p; } } void CreateList_t(List *L) //尾插法 { int i; int n; int goal; List *p; List *q=L; printf("请输入数据的个数:\n"); scanf("%d",&n); for (i=0;i data = goal; q -> next = p; q = p; } q -> next = NULL; } void InsList(List *L,int i,int e) //插入 { List *s; List *p = L; int j = 0; while (p&&jnext; ++j; } s = (struct List*)malloc(sizeof(struct List)); s -> data = e; //插入L中

单链表原地逆置(头插法)

原地逆置单链表(头插法) /* 原地逆置头插法伪算法 本函数使用的是带头节点的链表 1.将p指针指向有效数据的第二个节点 2.将p指针始终插入到phead后面,第一个有效节点前面,即插入到它俩中间位置,不论第一个有效节点是否被更改,这样就可以完全逆置单链表 3.p和q指针后移,直至移动到最后一个节点,完成插入操作 */ #include #include #include typedefstruct node { int data; struct node * next; }NODE,*PNODE; PNODE create_list(); //创建单链表函数声明 void traverse_list(PNODE phead); //输出单链表函数声明 PNODE reverse_list(PNODE phead); //逆置单链表函数声明 int main(void) { PNODE phead; phead = create_list(); traverse_list(phead); phead = reverse_list(phead); traverse_list(phead); return 0; }

PNODE create_list() { intval; PNODE phead,ptail,s; phead = (PNODE)malloc(sizeof(NODE)); if(phead == NULL) { printf("分配失败,程序终止\n"); exit(-1); } ptail=phead; printf("请输入每个节点的值,以-1结束\n"); scanf("%d",&val); while(val!=-1) { s=(PNODE)malloc(sizeof(NODE)); //新建一个节点 if(s == NULL) { printf("分配失败,程序终止\n"); exit(-1); } s->data = val; //s->next = NULL; ptail->next = s; //链接到节点后面 ptail = ptail->next; //使ptail永远指向最后一个节点 scanf("%d",&val); } ptail->next = NULL; printf("创建成功!\n"); returnphead; } voidtraverse_list(PNODE phead) { PNODE p; if(phead == NULL) { printf("链表为空,请创建链表!\n"); } else { p = phead->next;

数据结构___头插法和尾插法建立链表(各分有无头结点)

实验一链表的建立及基本操作方法实现 一、【实验目的】 、理解和掌握单链表的类型定义方法和结点生成方法。 、掌握利用头插法和尾插法建立单链表和显示单链表元素的算法。 、掌握单链表的查找(按序号)算法。 、掌握单链表的插入、删除算法。 二、【实验内容】 、利用头插法和尾插法建立一个无头结点单链表,并从屏幕显示单链表元素列表。 、利用头插法和尾插法建立一个有头结点单链表,并从屏幕显示单链表元素列表。 、将测试数据结果用截图的方式粘贴在程序代码后面。 重点和难点: 尾插法和头插法建立单链表的区别。 建立带头结点和无头结点单链表的区别。 带头结点和无头结点单链表元素显示方法的区别 三、【算法思想】 ) 利用头插法和尾插法建立一个无头结点单链表 链表无头结点,则在创建链表时,初始化链表指针。 当用头插法插入元素时,首先要判断头指针是否为空,若为空,则直接将新结点赋给,新结点指向空,即>,若表中已经有元素了,则将新结点的指向首结点,然后将新结点赋给即(>)。当用尾插法插入元素时,首先设置一个尾指针以便随时指向最后一个结点,初始化和头指针一样即。插入元素时,首先判断链表是否为空,若为空,则直接将新结点赋给即,若不为空,将最后一个元素的指向新结点即>,然后跳出这个语句,将新结点指向空,并且将指向新结点即>。 ) 利用头插法和尾插法建立一个有头结点单链表 链表有头结点,则在创建链表时,初始化链表指针> 。与无头结点区别在于,判断链表为空是根据>是否为空。 用头插法插入元素时,要判断链表是否为空,若为空则将新结点指向空,作为表尾,若不为空,则直接插入,将新结点指向头结点的指向,再将头结点指向新结点即>>>。 用尾插法插入元素时,首先也要设置一个尾指针以便随时指向最后一个结点,初始化,与无头结点区别就只是插入第一个元素时有区别。插入元素时,不需要判断链表是否为空,直接进行插入,代码>>。 )带头结点和无头结点单链表元素显示方法的区别: 区别在于,显示时带头结点是从头结点开始即>,而无头结点链表是直接从开始即。 四、【源程序代码】 ) 利用头插法和尾插法建立一个无头结点单链表 <>

排列组合 插板法 插空法 捆绑法

排列组合问题——插板法(分组)、插空法(不相邻)、捆绑法(相邻) 插板法(m为空的数量) 【基本题型】 有n个相同的元素,要求分到不同的m组中,且每组至少有一个元素,问有多少种分法? 图中“”表示相同的名额,“”表示名额间形成的空隙,设想在这几个空隙中插入六块“挡板”,则将这10 个名额分割成七个部分,将第一、二、三、……七个部分所包含的名额数分给第一、二、三……七所学校,则“挡板”的一种插法恰好对应了10 个名额的一种分配方法,反之,名额的一种分配方法也决定了档板的一种插法,即挡板的插法种数与名额的分配方法种数是相等的, 【总结】 需满足条件:n个相同元素,不同个m组,每组至少有一个元素,则只需在n个元素的n-1个间隙中放置m-1块隔板把它隔成m份即可,共有种不同方法。 注意:这样对于很多的问题,是不能直接利用插板法解题的。但,可以通过一定的转变,将其变成符合上面3个条件的问题,这样就可以利用插板法解决,并且常常会产生意想不到的效果。 插板法就是在n个元素间的(n-1)个空中插入若干个(b)个板,可以把n 个元素分成(b+1)组的方法. 应用插板法必须满足三个条件:

(1)这n个元素必须互不相异? (2)所分成的每一组至少分得一个元素? (3) 分成的组别彼此相异? 举个很普通的例子来说明? 把10个相同的小球放入3个不同的箱子,每个箱子至少一个,问有几种情况? 问题的题干满足条件(1)(2),适用插板法,c9 2=36? 下面通过几道题目介绍下插板法的应用? e 二次插板法? 例8 :在一张节目单中原有6个节目,若保持这些节目相对次序不变,再添加3个节目,共有几种情况? -o - o - o - o - o - o - 三个节目abc? 可以用一个节目去插7个空位,再用第二个节目去插8个空位,用最后个节目去插9个空位? 所以一共是c7 1×c8 1×c9 1=504种 【基本解题思路】 将n个相同的元素排成一行,n个元素之间出现了(n-1)个空档,现在我们用(m-1)个“档板”插入(n-1)个空档中,就把n个元素隔成有序的m份,每个组依次按组序号分到对应位置的几个元素(可能是1个、2个、3个、4

单链表完整算法

// 包含头文件 #include #include #include // 为结点数据类型和结构体类型起别名 typedefint datatype; typedefstructLinkNode { datatype data; // 数据域 structLinkNode *next; // 指针域存放下一个结点的地址}LNode,*LinkList; LinkList L; // 单链表的头指针 // 1.用头插法创建单链表 LinkListCreateListHead(int n) { // 创建头结点 LNode *L = (LNode *)malloc(sizeof(LNode)); L->next = NULL; // 设置指针域为空

LinkList p; // p指向新结点 for(inti=n;i>0;i--) // 先插入最后一个结点,插入次序与逻辑次序相反 { // 生成新结点 p = (LNode *)malloc(sizeof(LNode)); // 从键盘输入新结点的值 printf("请输入要插入第%d结点的值:\n",i); scanf("%d", &p->data); p->next = L->next; // 让L原来的后继结点成为p的后继结点 L->next = p; // p成为L新的后继结点 } return L; // 返回单链表的头指针 } // 2.用尾插法创建单链表 LinkListCreateListTail(int n) {

// 生成头结点 L = (LNode *)malloc(sizeof(LNode)); L->next = NULL;// 设置指针域为空 // p指向新结点,q指向尾结点 LinkList p, q = L; // 依次在末尾插入n个结点 for(inti=1;i<=n;i++) { // 生成新结点p p = (LNode *)malloc(sizeof(LNode)); // 从键盘输入新结点的值 printf("请输入第%d个结点的值:\n", i); scanf("%d",&p->data); p ->next = NULL; // 新结点(也是尾结点)的指针域为空 // 把新结点链接到单链表的末尾 q->next = p;

创建链表并实现插入、删除、输出,查找等功能

创建链表并实现插入、删除、输出,查找等功能 一、实验目的及内容 1、目的:通过上级操作,进一步了解线性表的存储结构以及基本运算。 2、内容: (1)、题目要求 编写程序,创建一个链表,实现链表的插、删除、查找和输出等功能。(2)、分析算法 单链表的建立,使用动态建立链表,有头插法建表和尾插法建表。 头插法建表: input_font() { head=NULL; datatype ch; puts("请输入您的数据,想结束输入,请键入“#”"); fflush(stdin); ch=getchar(); while(ch!='#') { p=(linklist *)malloc(sizeof(linklist)); p->c=ch; p->next=head; head=p; length++; puts("恭喜,你的数据输入正确!请继续操作!"); fflush(stdin); ch=getchar(); }

尾插法建表: input_end() { head=(linklist *)malloc(sizeof(linklist)); r=head; datatype ch; puts("请输入您的数据,想结束输入,请键入“#”"); fflush(stdin); ch=getchar(); while(ch!='#') { p=(linklist *)malloc(sizeof(linklist)); p->c=ch; r->next=p; r=p; length++; puts("恭喜,你的数据输入正确!请继续操作!"); fflush(stdin); ch=getchar(); } r->next=NULL; } (3)、流程图: 函数层次:

单链表的定义及其基本操作技巧

单链表的定义及基本操作 一、实验目的、意义 (1)理解线性表中带头结点单链表的定义和逻辑图表示方法。 (2)熟练掌握单链表的插入,删除和查询算法的设计与实现。 (3)根据具体问题的需要,设计出合理的表示数据的链表结构,并设计相关算法。 二、实验内容及要求 说明1:本次实验中的链表结构均为带头结点的单链表。 说明2: 学生在上机实验时,需要自己设计出所涉及到的函数,同时设计多组输入数据并编写主程序分别调用这些函数,调试程序并对相应的输出作出分析;修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。 具体要求: 建立单链表,完成链表(带表头结点)的基本操作:建立链表、插入、删除、查找、输出;其它基本操作还有销毁链表、将链表置为空表、求链表的长度、获取某位置结点的内容、搜索结点。 三、实验所涉及的知识点 数据结构、C语言语法函数、结构体类型指针、单链表(建表、初始化链表、求表长、插入、删除、查询算法)等。 四、实验结果及分析 (所输入的数据及相应的运行结果,运行结果要有提示信息,运行结果采用截图方式给出。)

五、总结与体会 (调试程序的心得与体会,若实验课上未完成调试,要认真找出错误并分析原因等。) 调试程序时,出现了许多错误。如:结构体类型指针出错,忽略了释放存储空间,对头插法建表、尾插法建表不熟悉等。另外还有一些语法上的错误。由于对所学知识点概念模糊,试验课上未能完成此次上机作业。后来经过查阅教材,浏览网页等方式,才完成试验。这次试验出现错误最重要的原因就是对课本知识点理解不深刻以及编写代码时的粗心。以后要都去练习、实践,以完善自己的不足。 六、程序清单(包含注释) //单链表

头插法与尾插法

#include #include typedef char DataType; //假设节点的数据类型为字符 typedef struct node{ //节点类型定义 DataType data; //节点的数据域 struct node *next; //节点的指针域 }ListNode; typedef ListNode* LinkList; ListNode *p; //指向某一节点的指针LinkList head; //单链表的头指针 //头插法 LinkList createListF(void); LinkList createListF(void){ //返回单链表的头指针 char ch; LinkList head; //头指针 ListNode *s; //工作指针 head = NULL; //链表开始为空

while (ch != '\n') { s = (ListNode*)malloc(sizeof(ListNode)); //生成新节点 s->data = ch; //将读入的数据放入新节点的数据域中 s->next = head; head = s; ch = getchar(); //读入下一个字符} return head; } //尾插法 LinkList createListR(void); LinkList createListR(void){ //返回头指针 char ch; LinkList head; //头指针 ListNode *s,*r; //工作指针 head = NULL; //链表开始为空 r = NULL; //尾指针初始值为空

数据结构头插法和尾插法建立单链表

#include #include typedef struct node { int data; struct node *next; }*Listlink; /*前插法创建单链表*/ void qian_create(Listlink *head,int n) { int i; Listlink p; *head=(Listlink )malloc(sizeof(struct node)); (*head)->next=NULL;/*建立头结点*/ printf("input %d numbers:\n",n); for(i=0;idata)); p->next=(*head)->next; (*head)->next=p; } } /*后插法创建单链表*/ void hou_create(Listlink *head,int n) { int i; Listlink p,q; *head=(Listlink )malloc(sizeof(struct node)); (*head)->next=NULL;/*建立头结点*/ q=*head; for(i=0;idata)); p->next=q->next; q->next=p; q=p; } }

void print_list(Listlink head) { Listlink p; p=head->next; while(p!=NULL) { printf(" %d",p->data); p=p->next; } } main() { Listlink la,lb,lc; puts("houcha:"); hou_create(&lb,10); puts("qiancha:"); qian_create(&la,10); print_list(la); print_list(lb); getchar(); }

头插法和尾插法建立单链表

#include "stdio.h" #include "stdlib.h" typedef struct List { int data; struct List *next; //指针域 }List; void HeadCreatList (List *L) //头插法建立链表 { List *s; L->next=NULL; for (int i=0;i<10;i++) { s=(struct List*)malloc(sizeof(struct List)); s->data=i; s->next=L->next; //将L指向的地址赋值给S; L->next=s; } } void TailCreatList(List *L) //尾插法建立链表 { List *s,*r; r=L;

for (int i=0;i<10;i++) { s=(struct List*)malloc(sizeof(struct List)); s->data=i; r->next=s; r=s; } r->next=NULL; } void DisPlay(List *L) { List *p=L->next; while(p!=NULL) { printf ("%d ",p->data); p=p->next; } printf("\n"); } int main () {

List *L1,*L2; L1=(struct List*)malloc(sizeof(struct List)); L2=(struct List*)malloc(sizeof(struct List)); HeadCreatList(L1); DisPlay(L1); TailCreatList(L2); DisPlay(L2); } //头插法创建链表 #include #include struct node { int data; struct node * next; }; //建立只含头结点的空链表 struct node * create_list() { struct node * head = NULL; head = (struct node *)malloc(sizeof(struct node)); if (NULL == head)

找两条单链表的公共结点

题目:两个单向链表,找出它们的第一个公共结点。 链表的结点定义为: struct ListNode { int m_nKey; ListNode* m_pNext; }; 分析:这是一道微软的面试题。微软非常喜欢与链表相关的题目,因此在微软的面试题中,链表出现的概率相当高。 如果两个单向链表有公共的结点,也就是说两个链表从某一结点开始,它们的m_pNext 都指向同一个结点。但由于是单向链表的结点,每个结点只有一个m_pNext,因此从第一个公共结点开始,之后它们所有结点都是重合的,不可能再出现分叉。所以,两个有公共结点而部分重合的链表,拓扑形状看起来像一个Y,而不可能像X。 看到这个题目,第一反应就是蛮力法:在第一链表上顺序遍历每个结点。每遍历一个结点的时候,在第二个链表上顺序遍历每个结点。如果此时两个链表上的结点是一样的,说明此时两个链表重合,于是找到了它们的公共结点。如果第一个链表的长度为m,第二个链表的长度为n,显然,该方法的时间复杂度为O(mn)。 接下来我们试着去寻找一个线性时间复杂度的算法。我们先把问题简化:如何判断两个单向链表有没有公共结点?前面已经提到,如果两个链表有一个公共结点,那么该公共结点之后的所有结点都是重合的。那么,它们的最后一个结点必然是重合的。因此,我们判断两个链表是不是有重合的部分,只要分别遍历两个链表到最后一个结点。如果两个尾结点是一样的,说明它们用重合;否则两个链表没有公共的结点。 在上面的思路中,顺序遍历两个链表到尾结点的时候,我们不能保证在两个链表上同时到达尾结点。这是因为两个链表不一定长度一样。但如果假设一个链表比另一个长l个结点,我们先在长的链表上遍历l个结点,之后再同步遍历,这个时候我们就能保证同时到达最后一个结点了。由于两个链表从第一个公共结点考试到链表的尾结点,这一部分是重合的。因此,它们肯定也是同时到达第一公共结点的。于是在遍历中,第一个相同的结点就是第一个公共的结点。 在这个思路中,我们先要分别遍历两个链表得到它们的长度,并求出两个长度之差。在长的链表上先遍历若干次之后,再同步遍历两个链表,知道找到相同的结点,或者一直到链表结束。此时,如果第一个链表的长度为m,第二个链表的长度为n,该方法的时间复杂度为O(m+n)。 基于这个思路,我们不难写出如下的代码: 1.template 2.struct ListNode

排列组合插板法插空法捆绑法

排列组合问题——插板法(分组)、插空法(不相邻)、捆绑法(相邻) 插板法(m为空得数量) 【基本题型】 有n个相同得元素,要求分到不同得m组中,且每组至少有一个元素,问有多少种分法? ? 图中“”表示相同得名额,“"表示名额间形成得空隙,设想在这几个空隙中插入六块“挡板”,则将这10 个名额分割成七个部分,将第一、二、三、……七个部分所包含得名额数分给第一、二、三……七所学校,则“挡板”得一种插法恰好对应了10 个名额得一种分配方法,反之,名额得一种分配方法也决定了档板得一种插法,即挡板得插法种数与名额得分配方法种数就是相等得, 【总结】?需满足条件:n个相同元素,不同个m组,每组至少有一个元素,则只需在n个元素 得n—1个间隙中放置m—1块隔板把它隔成m份即可,共有种不同方法。? 注意:这样对于很多得问题,就是不能直接利用插板法解题得。但,可以通过一定得转变,将其变成符合上面3个条件得问题,这样就可以利用插板法解决,并且常常会产生意想不到得效果。 插板法就就是在n个元素间得(n-1)个空中插入若干个(b)个板,可以把n个元素分成(b+1)组得方法.?应用插板法必须满足三个条件:?(1)这n个元素必须互不相异 (2)所分成得每一组至少分得一个元素 (3) 分成得组别彼此相异 举个很普通得例子来说明?把10个相同得小球放入3个不同得箱子,每个箱子至少一个,问有几种情况??问题得题干满足条件(1)(2),适用插板法,c9 2=36 ?下面通过几道题目介绍下插板法得应用?e 二次插板法 例8:在一张节目单中原有6个节目,若保持这些节目相对次序不变,再添加3个节目,共有几种情况? —o - o - o —o-o -o -三个节目abc?可以用一个节目去插7个空位,再用第二个节目去插8个空位,用最后个节目去插9个空位?所以一共就是c7 1×c81×c9 1=504种 【基本解题思路】 将n个相同得元素排成一行,n个元素之间出现了(n-1)个空档,现在我们用(m-1)个“档板”插入(n-1)个空档中,就把n个元素隔成有序得m份,每个组依次按组序号分到对应位置得几个元素(可能就是1个、2个、3个、4个、….),这样不同得插入办法就对应着n个相同得元素分到m组得一种分法,这种借助于这样得虚拟“档板”分配元素得方法称之为插板法。? 【基本题型例题】 【例1】共有10完全相同得球分到7个班里,每个班至少要分到一个球,问有几种不同分法??解析:我们可以将10个相同得球排成一行,10个球之间出现了9个空隙,现在我们用6个档板"插入这9个空隙中,就“把10个球隔成有序得7份,每个班级依次按班级序号分到对应位置得几个球(可能就是1个、2个、3个、4个),这样,借助于虚拟“档板"就可以把10个球分到了7个班中。? 【基本题型得变形(一)】 ?题型:有n个相同得元素,要求分到m组中,问有多少种不同得分法??解题思路:这种问题就是允许有些组中分到得元素为“0",也就就是组中可以为空得。对于这样得题,我们就首先将每组都填上1个,这样所要

相关文档
最新文档