数据结构___头插法和尾插法建立链表(各分有无头结点)
09-10学年第2学期数据结构试题(A卷)
2009~2010学年第二学期期末考试《数据结构》试题A一、选择题(每题2分,15题,共30分,请将答案写到后附答题纸的表格内)1、在数据结构的讨论中把数据结构从逻辑上分为()A )内部结构与外部结构 B)静态结构与动态结构C )线性结构与非线性结构D )紧凑结构与非紧凑结构。
2、对线性表进行二分查找时,要求线性表必须()。
A. 以链接方式存储,且数据元素有序B. 以链接方式存储C. 以顺序方式存储,且数据元素有序D. 以顺序方式存储3、若长度为n的线性表采用顺序存储结构存储,在第i个位置上插入一个新元素的时间复杂度为()A)O(n) B)O(1) C)O(n2) D)O(n3)4、顺序循环队列中(数组的大小为6),队头指示front和队尾指示rear的值分别为3和0,当从队列中删除1个元素,再插入2个元素后,front和rear的值分别为()A)5和1 B)2和4 C)1和5 D)4和25.在下列排序方法中,()的比较次数与记录的初始排列状态无关。
A. 直接插入排序B. 起泡排序C. 快速排序D. 简单选择排序6、设有数组A[i,j],数组的每个元素长度为3字节,i的值为1到8,j的值为1到10,数组从内存首地址BA开始顺序存放,当以列为主序存放时,元素A[5,8]的存储首地址为( )A)BA+41 B)BA+180 C)BA+222 D)BA+2257、下面哪个术语与数据的存储结构无关()A)顺序表B)链表C)散列表D)队列8、在一棵高度为k的满二叉树中,结点总数为()A)2k-1 B)2k C)2k-1D)⎣log2k⎦+19、一棵完全二叉树上有1001个结点,其中叶子结点的个数为()A)250 B)500 C)254 D)50110、利用二叉链表存储树,则根结点的右指针是()A)指向最左孩子 B)指向最右孩子 C)空 D)非空11、若邻接表中有奇数个边结点,则一定()A)图中有奇数个顶点B)图中有偶数个顶点C)图为无向图D)图为有向图12、无向图G=(V,E),其中:V={a,b,c,d,e,f},E={(a,b),(a,e),(a,c),(b,e),(c,f),(f,d),(e,d)},对该图进行深度优先遍历,得到的顶点序列正确的是()A)abecdf B)acfebd C)aebcfd D)aedfcb13、在一个带权连通图G中,权值最小的边一定包含在G的()A)最小生成树中B)深度优先生成树中C)广度优先生成树中D)深度优先生成森林中14、已知含10个结点的二叉排序树是一棵完全二叉树,则该二叉排序树在等概率情况下查找成功的平均查找长度等于()A)1.0 B)2.9 C)3.4 D)5.515、下面的序列中初始序列构成最小堆(小根堆)的是()A)10、60、20、50、30、26、35、40 B)70、40、36、30、20、16、28、10C)20、60、50、40、30、10、8、72 D)10、30、20、50、40、26、35、60 二、应用题(6题,共50分)1、已知一棵度为m的树中有n1个度为1的结点,n2个度为2的结点,……,n m个度为m的结点,问该树中有多少个叶子结点?要求写出分析过程。
国家开放大学电大《数据结构》网络课单项选择题题库及答案
国家开放大学电大《数据结构》网络课单项选择题题库及答案单项选择题题目1把数据存储到计算机中,并具体体现数据元素间的逻辑结构称为()。
选择一项:A. 算法的具体实现B. 逻辑结构C. 给相关变量分配存储单元D. 物理结构题目2下列说法中,不正确的是()。
选择一项:A. 数据项是数据中不可分割的最小可标识单位B. 数据元素是数据的基本单位C. 数据项可由若干个数据元素构成D. 数据可有若干个数据元素构成题目3一个存储结点存储一个()。
选择一项:A. 数据项B. 数据类型C. 数据元素D. 数据结构题目4数据结构中,与所使用的计算机无关的是数据的()。
选择一项:A. 存储结构B. 物理结构C. 逻辑结构D. 物理和存储结构题目5在线性表的顺序结构中,以下说法正确的是()。
选择一项:A. 进行数据元素的插入、删除效率较高B. 数据元素是不能随机访问的C. 逻辑上相邻的元素在物理位置上不一定相邻D. 逻辑上相邻的元素在物理位置上也相邻题目6对链表, 以下叙述中正确的是()。
选择一项:A. 可以通过下标对链表进行直接访问B. 插入删除元素的操作一定要要移动结点C. 不能随机访问任一结点D. 结点占用的存储空间是连续的题目7下列的叙述中,不属于算法特性的是()。
选择一项:A. 可行性B. 有穷性C. 可读性D. 输入性题目8算法的时间复杂度与()有关。
选择一项:A. 所使用的计算机B. 计算机的操作系统C. 数据结构D. 算法本身题目9设有一个长度为n的顺序表,要在第i个元素之前(也就是插入元素作为新表的第i个元素),插入一个元素,则移动元素个数为()。
选择一项:A. n-i-1B. iC. n-i+1D. n-i题目10设有一个长度为n的顺序表,要删除第i个元素移动元素的个数为()。
选择一项:A. iB. n-i-1C. n-iD. n-i+1题目11在一个单链表中,p、q分别指向表中两个相邻的结点,且q所指结点是p所指结点的直接后继,现要删除q所指结点,可用语句()。
头插法和尾插法建立单链表
#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 <stdio.h>#include <stdlib.h>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){printf("memory out of use/n");return NULL;}head->next = NULL;head->data = 0;return head;}//头插法建立链表int insert_form_head(struct node * head, int num){struct node * head_t = head->next;struct node * new_node = NULL;new_node = (struct node *)malloc(sizeof(struct node));if (NULL == new_node){printf("memory out of use/n");return -1;}//将新结点插入到链表的最后new_node->data = num;new_node->next = head_t;head->next = new_node;return 0;}//打印链表int show_list(struct node * head){struct node * temp;temp = head->next;while(temp){printf("%d/n",temp->data);temp = temp->next;}return 0;}// 按值删除结点,头结点不被删除int delete_node(struct node *head, int data){//head_t 保存要删除结点的上一个结点struct node * head_t = head;struct node * temp = NULL;if (head == NULL){printf("delete node from empty list!/n");return -1;}//查找删除的结点的前一个结点//如果此处查找的是删除的结点,则需要另加一个指针保存删除结点的前一个指针while(NULL != head_t->next){if (data == head_t->next->data)break;head_t = head_t->next;}//如果要删除的结点不存在,直接返回if (NULL==head_t->next){printf("node not found/n");return -1;}//删除操作temp = head_t->next;head_t->next = head_t->next->next;free(temp);return 0;}void main(int argc, char* argv[]){struct node * head;head = create_list();if (NULL == head)printf("create_list error/n");insert_form_head(head,123);insert_form_head(head,456);show_list(head);printf("delete once!/n");delete_node(head,123);show_list(head);printf("delete second!/n");delete_node(head,456);show_list(head);delete_node(head,0);show_list(head);}/*//尾插法创建链表#include<stdio.h>#include<stdlib.h>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){printf("memory out of use/n");return NULL;}head->next = NULL;head->data = 0;return head;//尾插法建立链表int insert_form_tail(struct Node * head, int num){struct Node * temp = head;struct Node * new_node = NULL;new_node = (struct Node *)malloc(sizeof(struct Node));if (NULL == new_node){printf("memory out of use/n");return -1;}//寻找尾结点while (temp->next != NULL){temp = temp->next;}//将新结点插入到链表的最后new_node->data = num;new_node->next = NULL;temp->next = new_node;return 0;}//打印链表int show_list(struct Node * head){struct Node * temp;temp = head->next;while(temp){printf("%d/n",temp->data);temp = temp->next;}return 0;}void main(int argc, char* argv[]){struct Node * head;head = create_list();if (NULL == head)printf("create_list error/n");insert_form_tail(head,123);insert_form_tail(head,456);show_list(head);*/。
尾插法建立单链表
如果我们在链表的开始结点之前附加一个 结点,并称它为头结点,那么会带来以下两个 优点: a、由于开始结点的位置被存放在头结点的指针 域中,所以在链表的第一个位置上的操作就和 在表的其它位置上的操作一致,无需进行特殊 处理; b、无论链表是否为空,其头指针是指向头结点 在的非空指针(空表中头结点的指针域为空), 因此空表和非空表的处理也就统一了。
尾插法建表 头插法建立链表虽然算法简单,但生成 的链表中结点的次序和输入的顺序相反。 若希望二者次序一致,可采用尾插法建表。 该方法是将新结点插入到当前链表的表尾 上,为此必须增加一个尾指针r,使其始终 指向当前链表的尾结点。
linklist creater( ) { char ch; linklist head; lnode *p,*r; //(, *head;) head=NULL; r=NULL; while ((ch=getchar( )!=‵\n′){ p=(lnode *)malloc(sizeof(lnode)); p–>data=ch; if (head=NULL) head=p; else r–>next=p; r=p; } if (r!=NULL) r–>next=NULL; r,将开始结点 插入到空表中,是在当前链表的第一个位置上插 入,该位置上的插入操作和链表中其它位置上的 插入操作处理是不一样的,原因是开始结点的位 置是存放在头指针(指针变量)中,而其余结点 的位置是在其前趋结点的指针域中。 算法中的第一个if语句就是用来对第一个位置上的 插入操作做特殊处理。算法中的第二个if语句的 作用是为了分别处理空表和非空表两种不同的情 况,若读入的第一个字符就是结束标志符,则链 表head是空表,尾指针r亦为空,结点*r不存在; 否则链表head非空,最后一个尾结点*r是终端结 点,应将其指针域置空。
《数据结构》-头插法建立单链表
LinkList head;
ListNode *s;
head=NULL;
printf("请输入链表各结点的数据(字符型):\n");
while((ch=getchar())!='\n')
{
s=(ListNode *)malloc(sizeof(ListNode ));
if(s==NULL)
{
printf("申请存储空间失败!");return head;
2020
数据结构
Data structure
头插法建立单链表
讲授:XXX
0.5 头插法建立单链表
要 假三设求、线:性链表表中的结插点入的数据类型是字符型,逐个输入这些字符,并以换行符‘\n’作为输入结束的条
件,使用头插法动态地建立单链表(不带头结点)。
算法思路:
从一个空表开始,重复读入数据,生成新结点,将读入数据存放在新结点的数据域中,然后将新结 点插入到当前链表的表头上,直到读入换行符'\n'为止。
图2-6 新结点前插
图2-7 头指针指向新结点
重复进行第②步到第⑥步,便可建立一个含有多个结点的 不带头结点的单链表,如图2-8。
head s
d
c
b
a^
图2-8 头插法建单链表
04
0.5
05
头插法建立单链表
具体算法:
LinkList CreatListF(void)
{//头插法建立单链表
DataType ch;
算法步骤:
①将头指针head置为
②读取字符ch,判断ch与'\n'是否不相
NULL,转向②。如图2-3。 等,若是转向③,否则,返回head。
数据结构与算法题库下发版
数据结构与算法题库下发版一、单选题知识点一:绪论1.设有如下遗产继承规则:丈夫和妻子可以互相继承遗产;子女可以继承父亲或母亲的遗产:子女间不能相互继承。
则表示该遗产继承关系的最合适数据结构应该是( )。
A(树 B.图 C.数组 D.二叉树2.设有一遗传关系:X是Y的父亲,X可以把它的属性遗传给Y。
则表示该遗传关系最适合的数据结构为( )。
A.向量B.树C.图D.广义表3.在数据结构中,从逻辑上可以把数据结构分成 ( )A.动态结构和静态结构B.紧凑结构和非紧凑结构C.线性结构和非线性结构D.内部结构和外部结构4.数据结构在计算机内存中的表示是指 ( )A.数据的存储结构B.数据结构C.数据的逻辑结构D.数据元素之间的关系 5. 计算机算法指( )A.计算方法B.排序方法C.解决问题的有限运算序列D.调度方法6. 在以下的叙述中,正确的是A.线性表的线性存储结构优于链表存储结构B.二维数组是其数据元素为线性表的线性表C.校的操作方式是先进先出D.队列的操作方式是先进后出在决定选取何种存储结构时,一般不考虑( ) 7.A.各结点的值如何B.结点个数的多少C.对数据有哪些运算D.所用编程语言实现这种结构是否方便8. 在存储数据时,通常不仅要存储各数据元素的值,而且还要存储( ) A.数据的处理方法B.数据元素的类型 C.数据元素之间的关系D.数据的存储方法 9.以下说法正确的是( )A.数据元素是数据的最小单位B.数据项是数据的基本单位C.数据结构是带结构的数据项的集合D.一些表面上很不相同的数据可以有相同的逻辑结构10(设计一个“好”的算法应达到的目标为( )。
A.正确性、可读性、健壮性及效率与低存储量需求B.正确性、可读性、健壮性及有穷性 C.正确性、可读性、健壮性及可行性 D.正确性、可读性、健壮性及确定性知识点二:线性表11.与线性表的链接存储相符的特性是( )。
A.插入和删除操作灵活B.需要连续存储空间C.便于随机访问D.存储密度大12.在单向循环链表中,若头指针为h,那么p所指结点为尾结点的条件是( )。
《数据结构——C语言描述》习题及答案耿国华
第1章绪论习题一、问答题1. 什么是数据结构?2. 四类基本数据结构的名称与含义。
3. 算法的定义与特性。
4. 算法的时间复杂度。
5. 数据类型的概念。
6. 线性结构与非线性结构的差别。
7. 面向对象程序设计语言的特点。
8. 在面向对象程序设计中,类的作用是什么?9. 参数传递的主要方式及特点。
10.抽象数据类型的概念。
二、判断题1. 线性结构只能用顺序结构来存放,非线性结构只能用非顺序结构来存放。
2. 算法就是程序。
3. 在高级语言(如C、或PASCAL)中,指针类型是原子类型。
三、计算下列程序段中XX1 的语句频度fori1iltni forj1jltij fork1kltjk xx1 提示: i1 时:1 11×1/2 112/2 i2 时:12 12×2/2 222/2 i3 时:123 13×3/2 332/2 … in 时:123……n 1n×n/2 nn2/2 fn 123……n 12 22 32 …… n2 / 2 1nn/2 nn12n1/6 / 2 nn1n2/6 n3/6n2/2n/3区分语句频度和算法复杂度:Ofn On3 四、试编写算法求一元多项式Pnxa0a1xa2x2a3x3…anxn 的值Pnx0,并确定算法中的每一语句的执行次数和整个算法的时间复杂度,要求时间复杂度尽可能的小,规定算法中不能使用求幂函数。
注意:本题中的输入aii01…n x 和n,输出为Pnx0.通常算法的输入和输出可采用下列两种方式之一:(1)通过参数表中的参数显式传递;(2)通过全局变量隐式传递。
试讨论这两种方法的优缺点,并在本题算法中以你认为较好的一种方式实现输入和输出。
提示:floatPolyValuefloat a float x int n…… 核心语句:p1 x 的零次幂s0 i 从0 到n 循环ssaip ppx 或:px x 的一次幂sa0 i 从1 到n 循环ssaip ppx 实习题设计实现抽象数据类型“有理数”。
《数据结构》练习题库
二、填空题1. 线性表是一种典型的___线性______结构。
2. 在一个长度为n的顺序表的第i个元素之前插入一个元素,需要后移__n-i+1__个元素。
3. 顺序表中逻辑上相邻的元素的物理位置__相邻______。
4. 要从一个顺序表删除一个元素时,被删除元素之后的所有元素均需向__前___移一个位置,移动过程是从_前____向_后____依次移动每一个元素。
5. 在线性表的顺序存储中,元素之间的逻辑关系是通过__物理存储位置_____决定的;在线性表的链接存储中,元素之间的逻辑关系是通过__链域的指针值_____决定的。
6. 在双向链表中,每个结点含有两个指针域,一个指向___前趋____结点,另一个指向____后继___结点。
7. 当对一个线性表经常进行存取操作,而很少进行插入和删除操作时,则采用___顺序__存储结构为宜。
相反,当经常进行的是插入和删除操作时,则采用__链接___存储结构为宜。
8. 顺序表中逻辑上相邻的元素,物理位置__一定_____相邻,单链表中逻辑上相邻的元素,物理位置___不一定____相邻。
9. 线性表、栈和队列都是__线性_____结构,可以在线性表的___任何___位置插入和删除元素;对于栈只能在___栈顶____位置插入和删除元素;对于队列只能在___队尾____位置插入元素和在___队头____位置删除元素。
10. 根据线性表的链式存储结构中每个结点所含指针的个数,链表可分为__单链表_______和__双链表_____;而根据指针的联接方式,链表又可分为__循环链表______和__非循环链表______。
11. 在单链表中设置头结点的作用是__使空表和非空表统一______。
12. 对于一个具有n个结点的单链表,在已知的结点p后插入一个新结点的时间复杂度为_o(1)_____,在给定值为x的结点后插入一个新结点的时间复杂度为__o(n)_____。
13. 对于一个栈作进栈运算时,应先判别栈是否为__栈满_____,作退栈运算时,应先判别栈是否为_栈空______,当栈中元素为m时,作进栈运算时发生上溢,则说明栈的可用最大容量为___m____。
尾插法建表
尾插法建表1. 什么是尾插法建表尾插法建表是一种在链表数据结构中,通过不断在链表尾部插入新的节点来构建链表的方法。
它是一种简单而高效的链表构建方式,适用于需要动态添加节点的场景。
2. 尾插法建表的原理尾插法建表的原理非常简单,主要包括以下几个步骤:1.创建一个空链表,将链表头指针指向空。
2.依次输入节点的值,创建新的节点,并将节点的值赋给新节点的数据域。
3.将新节点插入到链表的尾部,即将新节点的地址赋给链表中最后一个节点的指针域,并更新链表尾指针。
4.重复步骤2和3,直到所有节点都插入到链表中。
3. 尾插法建表的步骤尾插法建表的具体步骤如下:1.创建一个空链表,将链表头指针指向空。
2.输入节点的值,创建新的节点,并将节点的值赋给新节点的数据域。
3.判断链表是否为空,如果为空,则将新节点作为链表的第一个节点,即将新节点的地址赋给链表头指针,并将链表尾指针指向新节点。
4.如果链表不为空,将新节点插入到链表的尾部。
首先将链表的尾指针指向新节点,然后将新节点的地址赋给链表中最后一个节点的指针域,并更新链表尾指针。
5.重复步骤2到4,直到所有节点都插入到链表中。
4. 尾插法建表的示例下面通过一个具体的示例来演示尾插法建表的过程。
假设我们要构建一个包含5个节点的链表,节点的值分别为1、2、3、4、5。
首先,我们创建一个空链表,将链表头指针指向空。
head -> NULL然后,我们输入节点的值,并创建新的节点。
输入节点1,创建新节点A,将节点值1赋给新节点的数据域。
head -> NULL|A -> 1 -> NULL输入节点2,创建新节点B,将节点值2赋给新节点的数据域。
head -> NULL|A -> 1 -> NULL|B -> 2 -> NULL输入节点3,创建新节点C,将节点值3赋给新节点的数据域。
head -> NULL|A -> 1 -> NULL|B -> 2 -> NULL|C -> 3 -> NULL输入节点4,创建新节点D,将节点值4赋给新节点的数据域。
建立链表—头插法、尾插法—有无头结点
建⽴链表—头插法、尾插法—有⽆头结点1.建⽴链表-头插法-头结点1//建⽴链表-头插法-头结点2 LinkList CreatList_head()3 {4 DataType x; //数据5 LinkList p,head; //结点6 head = (LinkList)malloc(sizeof(LNode));7 head->next = NULL;8 head->data = 0;910 scanf("%d",&x);11while(x != 999)12 {13 p = (LinkList)malloc(sizeof(LNode));14 p->data = x; //存数据15 p->next = head->next;16 head->next = p;17 head->data++; //结点计数18 scanf("%d",&x);19 }20return head;21 }2223//输出链表-头插法-头结点24void PrintList_head(LinkList p)25 {26 LinkList a;27 a = p->next;28while(a != NULL)29 {30 printf("%d ",a->data);31 a = a->next;32 }33 printf("\n");34 }2.建⽴链表-头插法-⽆头结点1//建⽴链表-头插法-⽆头结点2 LinkList CreatList()3 {4 DataType x;5 LinkList p,head;6 head = NULL;78 scanf("%d",&x);9while(x != 999)10 {11 p = (LinkList)malloc(sizeof(LNode));12 p->data = x;13if(head == NULL)14 { head = p;15 p->next = NULL;16 }17else18 {19 p->next = head;20 head = p;21 }22 scanf("%d",&x);23 }24return head;25 }262728//输出链表-头插法-⽆头结点29void PrintList(LinkList p)30 {31 LinkList a;32 a = p;33while(a != NULL)34 {35 printf("%d ",a->data);36 a = a->next;37 }38 printf("\n");39 }3.建⽴链表-尾插法-⽆头结点 1//建⽴链表-头插法-⽆头结点2 LinkList CCC()3 {4 DataType x;5 LinkList p,head;6 head = NULL;78 scanf("%d",&x);9while(x != 999)10 {11 p = (LinkList)malloc(sizeof(LNode));12 p->data = x;13 p->next = head;14 head = p;1516 scanf("%d",&x);17 }18return head;19 }202122//输出链表-头插法-⽆头结点23void PPP(LinkList p)24 {25 LinkList a;26 a = p;27while(a != NULL)28 {29 printf("%d ",a->data);30 a = a->next;31 }32 printf("\n");33 }4.建⽴链表-尾插法-头结点 1//建⽴链表-尾插法-头结点2 LinkList Tailhead()3 {4 DataType x;5 LinkList p,head,r;6 head = (LinkList)malloc(sizeof(LNode));7 head->next = NULL;8 r = head;9 scanf("%d",&x);10while(x != 999)11 {12 p = (LinkList)malloc(sizeof(LNode));13 p->data = x;14 p->next = r->next;15 r->next = p;16 r = p;17 scanf("%d",&x);18 }1920return head;21 }22//输出链表-尾插法-头结点23void PrintTailhead(LinkList p)24 {25 LinkList a;26 a = p->next;27while(a != NULL)28 {29 printf("%d ",a->data);30 a = a->next;31 }32 printf("\n");33 }。
链式存储(头插法、尾插法)
链式存储(头插法、尾插法)#include "stdio.h"#include "string.h"#include "ctype.h"#include "stdlib.h"#include "io.h"#include "math.h"#include "time.h"#define OK 1#define ERROR 0#define TRUE 1#define FALSE 0#define MAXSIZE 20 // 存储空间初始分配量typedef int Status;// Status是函数的类型,其值是函数结果状态代码。
如OK等typedef int ElemType;//ElemType类型依据实际情况⽽定,这⾥如果为intStatus visit(ElemType c){printf("%d ",c);return OK;}typedef struct Node{ElemType data;struct Node *next;}Node;typedef struct Node *LinkList; // 定义LinkList// 初始化顺序线性表Status InitList(LinkList *L){*L=(LinkList)malloc(sizeof(Node)); // 产⽣头结点,并使L指向此头结点if(!(*L)) // 存储分配失败return ERROR;(*L)->next=NULL; //指针域为空return OK;}//初始条件:顺序线性表L已存在。
操作结果:若L为空表,则返回TRUE,否则返回FALSEStatus ListEmpty(LinkList L){if(L->next)return FALSE;elsereturn TRUE;}// 初始条件:顺序线性表L已存在。
《数据结构》05级(计算机)期末考试A卷(1)
东莞理工学院(本科)试卷(A 卷)2006 -2007 学年第二学期开课单位:软件学院,考试形式:闭卷,允许带入场科目:数据结构与算法分析班级:姓名:学号:一、填空题(每小题2分,共18分)1、对于给定的n个元素,可以构造出的逻辑结构有集合, ,和四种。
2、数据结构中评价算法的两个重要指标是和。
3、数据类型指的是和定义在的总称。
4、顺序存储结构是通过表示数据元素之间的(逻辑)关系;链式存储结构是通过表示数据元素之间的(逻辑)关系。
5、栈是的线性表,其操作数据的基本原则是。
6、设有一个二维数组A[0…9][0…9],若每个元素占3个基本存储单元,A[0][0]的地址是600,若按行优先(以行为主)顺序存储,则A[6][8]的存储地址是。
7、树的先序遍历实质上与将树转换成二叉树后对二叉树的相同;而树的后序遍历实质上与将树转换成二叉树后对二叉树的相同。
8、若采用邻接矩阵存储一个图所需要的存储单元取决于图的;无向图的邻接矩阵一定是。
9、对于一个有n个顶点的完全无向图,具有条边;而对于一个有n个顶点的完全有向图,具有条弧。
二、单项选择题(请将答案写在题目后的括号中。
每题2分,共18分)1、有算法sum(n),其时间复杂度是( A )。
sum( int n ){ int sum=0, m, t ;for (m=1; m<=n; m++){ p=1 ;for (t=1; t<=m; t++) p*=t ;sum+=p ;}return (sum) ;}(A)O(n2) (B)O(m2) (C)O(m+n) (D)O(n×m)2、设p是非空单链表中结点q的直接前驱结点,删除q的正确操作是( B )。
(A)p->next=q->next;free(p) ; (B)p->next= q->next;free(q) ;(C)q->next=p->next;free(p) ; (D)q->next=p->next;free(q) ;3、设有一个栈顶指针为top的顺序栈S,top为0时表示栈空,则从S中取出一个元素保存在P中执行的操作是( D )。
尾插法建表
尾插法建表尾插法是一种常用的链表建表方法,它可以快速构建一个具有动态长度的链表。
在尾插法建表中,我们通过依次读入数据,并将其插入到链表的尾部,从而逐渐构建出完整的链表结构。
1. 算法原理尾插法建表的算法原理非常简单直观:1.创建一个空链表,用头指针head指向链表的头节点。
2.读取第一个数据,并创建一个新节点node。
3.如果链表为空,则将node作为第一个节点,即将head指向node。
4.如果链表不为空,则找到当前链表最后一个节点last,并将last的next指针指向node。
5.将node作为新的最后一个节点,并更新last为node。
6.重复步骤2-5,直到读取完所有数据。
2. 代码实现下面是使用Python语言实现尾插法建表的示例代码:class ListNode:def __init__(self, val=0, next=None):self.val = valself.next = nextdef createLinkedList(nums):head = ListNode()last = headfor num in nums:node = ListNode(num)last.next = nodelast = nodereturn head.next3. 示例假设我们要使用尾插法建立一个包含4个节点的链表,数据依次为1、2、3、4。
nums = [1, 2, 3, 4]head = createLinkedList(nums)# 打印链表while head:print(head.val)head = head.next输出结果为:12344. 时间复杂度分析尾插法建表的时间复杂度为O(n),其中n为链表的长度。
这是因为每个数据都需要进行一次插入操作,而每次插入操作的时间复杂度是O(1)。
因此,整个建表过程的时间复杂度就是O(n)。
5. 空间复杂度分析尾插法建表的空间复杂度为O(n),其中n为链表的长度。
数据结构___头插法和尾插法建立链表(各分有无头结点)
实验一链表的建立及基本操作方法实现一、【实验目的】1、理解和掌握单链表的类型定义方法和结点生成方法。
2、掌握利用头插法和尾插法建立单链表和显示单链表元素的算法。
3、掌握单链表的查找(按序号)算法。
4、掌握单链表的插入、删除算法。
二、【实验内容】1、利用头插法和尾插法建立一个无头结点单链表,并从屏幕显示单链表元素列表。
2、利用头插法和尾插法建立一个有头结点单链表,并从屏幕显示单链表元素列表。
3、将测试数据结果用截图的方式粘贴在程序代码后面。
重点和难点:尾插法和头插法建立单链表的区别。
建立带头结点和无头结点单链表的区别。
带头结点和无头结点单链表元素显示方法的区别三、【算法思想】1) 利用头插法和尾插法建立一个无头结点单链表链表无头结点,则在创建链表时,初始化链表指针L=NULL。
当用头插法插入元素时,首先要判断头指针是否为空,若为空,则直接将新结点赋给L,新结点next指向空,即L=p,p->next=NULL,若表中已经有元素了,则将新结点的next指向首结点,然后将新结点赋给L即(p->next=L,L=p)。
当用尾插法插入元素时,首先设置一个尾指针tailPointer以便随时指向最后一个结点,初始化tailPointer和头指针一样即tailPointer=L。
插入元素时,首先判断链表是否为空,若为空,则直接将新结点赋给L即L=p,若不为空,else将最后一个元素的next指向新结点即tailPointer->next=p,然后跳出这个if,else语句,将新结点next指向空,并且将tailPointer指向新结点即p->next=NULL,tailPointer=p。
2) 利用头插法和尾插法建立一个有头结点单链表链表有头结点,则在创建链表时,初始化链表指针L->next = NULL。
与无头结点区别在于,判断链表为空是根据L->next是否为空。
用头插法插入元素时,要判断链表是否为空,若为空则将新结点next指向空,作为表尾,若不为空,则直接插入,将新结点next指向头结点next的指向,再将头结点next指向新结点即p->next=L->next,L->next=p。
数据结构-头插法和尾插法
数据结构-头插法和尾插法1.头插法
void HeadCreatList(List *L) //头插法建⽴链表
{
List *s; //不⽤像尾插法⼀样⽣成⼀个终端节点。
L->next = NULL;
for (int i = 0; i < 10; i++) {
s = (struct List*) malloc(sizeof(struct List));//s指向新申请的节点
s->data = i;//⽤新节点的数据域来接受i
s->next = L->next; //将L指向的地址赋值给S;//头插法与尾插法的不同之处主要在此,
//s所指的新节点的指针域next指向L中的开始节点
L->next = s; //头指针的指针域next指向s节点,使得s成为开始节点。
}
2.尾插法
void TailCreatList(List *L) //尾插法建⽴链表
{
List *s, *r;//s⽤来指向新⽣成的节点。
r始终指向L的终端节点。
r = L; //r指向了头节点,此时的头节点是终端节点。
for (int i = 0; i < 10; i++) {
s = (struct List*) malloc(sizeof(struct List));//s指向新申请的节点
s->data = i; //⽤新节点的数据域来接受i
r->next = s; //⽤r来接纳新节点
r = s; //r指向终端节点
}
r->next = NULL; //元素已经全部装⼊链表L中
//L的终端节点指针域为NULL,L建⽴完成。
c语言链表的创建方法
c语言链表的创建方法链表是一种常见的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
链表的创建方法是链表的基础,本文将介绍以C语言为例的链表创建方法。
链表的创建方法可以分为两种:头插法和尾插法。
头插法是将新节点插入链表的头部,尾插法是将新节点插入链表的尾部。
下面分别介绍这两种方法的实现。
头插法创建链表头插法创建链表的基本思路是:先创建一个头节点,然后依次插入新节点。
新节点插入到头节点之后,成为新的头节点。
具体实现步骤如下:1. 定义链表节点结构体链表节点结构体包含两个成员变量:数据元素和指向下一个节点的指针。
定义如下:```typedef struct Node {int data;struct Node* next;} Node;```2. 创建头节点头节点是链表的第一个节点,它不包含数据元素,只有一个指向下一个节点的指针。
创建头节点的代码如下:```Node* head = (Node*)malloc(sizeof(Node));head->next = NULL;```3. 插入新节点插入新节点的代码如下:```Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->next = head->next;head->next = newNode;```其中,value是新节点的数据元素。
4. 循环插入新节点循环插入新节点的代码如下:```int i;for (i = 0; i < n; i++) {int value;scanf("%d", &value);Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = value;newNode->next = head->next;head->next = newNode;}```其中,n是要插入的节点数。
数据结构之单链表头插法,尾插法
数据结构之单链表头插法,尾插法数据结构之单链表头插法,尾插法单链表是中的⼀种,单链表的头插法也称前插法。
链表也是线性表的⼀种,与顺序表不同的是,它在内存中不是连续存放的。
在C语⾔中,链表是通过指针相关实现的。
⽽单链表是链表的其中⼀种,关于单链表就是其节点中有数据域和只有⼀个指向下个节点的指针域。
创建单链表的⽅法有两种,分别是头插法和尾插法。
所谓头插法,就是按节点的逆序⽅法逐渐将结点插⼊到链表的头部。
反之尾插法就是按节点的顺序逐渐将节点插⼊到链表的尾部。
相对来说,头插法要⽐尾插法算法简单,但是最后产⽣的链表是逆序的,即第⼀个输⼊的节点实际是链表的最后⼀个节点。
⽽为了习惯,通常⽤尾插法来创建链表。
下⾯的代码就是实现了头插法和尾插法创建头节点//创建头结点Node* Create_List (){//创建头结点Node* list = (Node*) malloc(sizeof(Node) / sizeof(char));if (NULL == list) //检验创建是否成功{return FALSE;}list->next = NULL;return list;}头插法// 头插法int Insert_Last (Node* h, LinkData data){// 判断数据传⼊是否正确if (NULL == h){return FALSE;}// 创建新结点并判断创建是否成功Node* node = (Node*) malloc(sizeof(Node) / sizeof(char));if (NULL == node){return FALSE;}// 给结点成员变量赋值node->data = data;node->next = h->next; // 和头指针的不同:node->next = *h;// 让新结点变为链表的第⼀个节点h->next = node;return TRUE;}尾插法//尾插int Insert_Last(Node* h, LinkData data){if (NULL == h){return FALSE;}// 创建新结点并判断创建是否成功Node* node = (Node*) malloc(sizeof(Node) / sizeof(char));if (NULL == node){return FALSE;}// 给结点成员变量赋值node->data = data;node->next = NULL;// 让新结点变为链表的最后⼀个节点Node* tmp = h;while(tmp->next){tmp = tmp->next;}//找到链表的尾节点并令尾节点指向nodetmp->next = node;return TRUE;}扩充中间插⼊//中间插⼊法int Insert_Pos(Node *h, int pos, LinkData data){//判断链表是否存在if (NULL == h){return FALSE;}Node* tmp = h;int i;for (i = 0; i < pos - 1; i++){if (NULL == tmp){break;}tmp = tmp->next;}//判断tmp是否存在if (NULL == tmp){printf ("插⼊位置越界");return FALSE;}Node* node = (Node*) malloc(sizeof(Node) / sizeof(char)); if (NULL == node){return FALSE;}node->data = data;node->next = tmp->next;tmp->next = node;return TRUE;}。
数据结构中链表的头插法和尾插法
数据结构中链表的头插法和尾插法头插法:头插法图解:解释:头插法顾名思义就是在头结点的后⾯增加结点。
⾸先创建⼀个带头结点的空的单链表head其次按照线性表中元素的逆序依次读⼊数据元素,如果不是结束标志时,申请结点s,将s结点插⼊到头结点之后。
如上图b。
#include<stdio.h>#include<stdlib.h>#include<malloc.h>typedef int elemtype;typedef struct node{elemtype data;struct node *next;}LNode *LinkList;LinkList CreatFromHead(){LinkList head;LNode *s;char c;int flag = 1;/*设置⼀个标识变量flag,初值为1,当输⼊“$”时,将flag置位0,建表结束*/head = (LinkList)malloc(sizeof(LNode));head->next = NULL;while(flag){c = getchar();if(c!='$'){s = (LinkList)malloc(sizeof(LNode));s->data = c;s->next = head->next;/*将s插⼊到链表中第⼀个数据元素之前*/head->next = s;}elseflag = 0;/*读⼊的符号为"$",修改结束标识*/}return head;}尾插法:尾插法图解:解释:头插法读⼊的数据元素的顺序与⽣成的链表中数据元素的顺序是相反的。
所以⽤尾插法就可以很好解决这个问题。
因为每次都必须将新结点插⼊到链表的尾部,所以需要加⼊⼀个尾指针r,⽤来始终指向链表的尾结点,以便能够将新结点插⼊到链表的尾部。
#include<stdio.h>#include<stdlib.h>#include<malloc.h>typedef int elemtype;typedef struct node{elemtype data;struct node *next;}LNode *LinkList;LinkList CreatTailHead(){LinkList L;LNode *s;char c;int flag = 1;/*设置⼀个标识变量flag,初值为1,当输⼊“$”时,将flag置位0,建表结束*/L = (LinkList)malloc(sizeof(LNode)); //为头结点分配空间L->next = NULL; //建带头结点的空链表r = L; //尾指针r指向表尾while(flag){c = getchar();if(c!='$'){s = (LinkList)malloc(sizeof(LNode));s->data = c;r-next = s; //插⼊到表尾r = s;}else{flag = 0;r-next = NULL;}}return L;}。
c语言单链表尾插法
c语言单链表尾插法【实用版】目录1.介绍 C 语言单链表2.解释尾插法3.演示如何使用尾插法创建单链表4.讨论尾插法的优缺点正文一、介绍 C 语言单链表单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两个部分:数据域和指针域。
数据域用于存储数据,指针域则指向下一个节点。
单链表中只有一个头节点,但没有尾节点。
在 C 语言中,我们可以使用结构体来定义单链表的节点。
二、解释尾插法尾插法是一种在单链表尾部插入新节点的方法。
这种方法的主要优点是在插入新节点时,不需要遍历整个链表,因此插入操作的时间复杂度为O(1)。
尾插法的基本思想是创建一个新节点,将其指针域指向原链表的尾节点,然后将新节点的数据域与原链表的尾节点的数据域进行连接。
三、演示如何使用尾插法创建单链表以下是使用尾插法创建单链表的示例代码:```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node *next;} Node;// 创建新节点ode *createNode(int data) {Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = data;newNode->next = NULL;return newNode;}// 在链表尾部插入新节点void insertNodeAtTail(Node **head, int data) {Node *newNode = createNode(data);newNode->next = *head;*head = newNode;}// 打印链表void printList(Node *head) {Node *current = head;while (current!= NULL) {printf("%d -> ", current->data);current = current->next;}printf("NULL");}int main() {Node *head = NULL;insertNodeAtTail(&head, 1);insertNodeAtTail(&head, 2);insertNodeAtTail(&head, 3);printList(head);return 0;}```四、讨论尾插法的优缺点尾插法的主要优点是插入新节点时,不需要遍历整个链表,因此插入操作的时间复杂度为 O(1)。
数据结构循环链表头插法介绍
数据结构循环链表头插法介绍
循环链表是一种特殊的链表,它的最后一个节点指向头节点,形成一个环形结构。
循环链表可以通过头插法来进行节点的插入。
头插法是指将新节点插入到链表的头部。
具体操作如下:
1. 创建一个新节点,并给新节点赋值。
2. 将新节点的next指针指向原链表的头节点。
3. 找到原链表的尾节点,并将其next指针指向新节点。
4. 将原链表的头节点指向新节点,完成节点的插入。
使用头插法插入节点到循环链表中,头节点指针的更新比较简单,只需要将新节点作为头节点即可。
因为循环链表的尾节点的next指针指向头节点,所以在更新尾节点的next指针时,将其指向新节点即可完成节点的插入。
头插法的时间复杂度为O(1),适用于循环链表中节点的插入操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一链表的建立及基本操作方法实现一、【实验目的】1、理解和掌握单链表的类型定义方法和结点生成方法。
2、掌握利用头插法和尾插法建立单链表和显示单链表元素的算法。
3、掌握单链表的查找(按序号)算法。
4、掌握单链表的插入、删除算法。
二、【实验内容】1、利用头插法和尾插法建立一个无头结点单链表,并从屏幕显示单链表元素列表。
2、利用头插法和尾插法建立一个有头结点单链表,并从屏幕显示单链表元素列表。
3、将测试数据结果用截图的方式粘贴在程序代码后面。
重点和难点:尾插法和头插法建立单链表的区别。
建立带头结点和无头结点单链表的区别。
带头结点和无头结点单链表元素显示方法的区别三、【算法思想】1) 利用头插法和尾插法建立一个无头结点单链表链表无头结点,则在创建链表时,初始化链表指针L=NULL。
当用头插法插入元素时,首先要判断头指针是否为空,若为空,则直接将新结点赋给L,新结点next指向空,即L=p,p->next=NULL,若表中已经有元素了,则将新结点的next指向首结点,然后将新结点赋给L即(p->next=L,L=p)。
当用尾插法插入元素时,首先设置一个尾指针tailPointer以便随时指向最后一个结点,初始化tailPointer和头指针一样即tailPointer=L。
插入元素时,首先判断链表是否为空,若为空,则直接将新结点赋给L即L=p,若不为空,else将最后一个元素的next指向新结点即tailPointer->next=p,然后跳出这个if,else语句,将新结点next指向空,并且将tailPointer指向新结点即p->next=NULL,tailPointer=p。
2) 利用头插法和尾插法建立一个有头结点单链表链表有头结点,则在创建链表时,初始化链表指针L->next = NULL。
与无头结点区别在于,判断链表为空是根据L->next是否为空。
用头插法插入元素时,要判断链表是否为空,若为空则将新结点next指向空,作为表尾,若不为空,则直接插入,将新结点next指向头结点next的指向,再将头结点next指向新结点即p->next=L->next,L->next=p。
用尾插法插入元素时,首先也要设置一个尾指针tailPointer以便随时指向最后一个结点,初始化tailPointer=L,与无头结点区别就只是插入第一个元素时有区别。
插入元素时,不需要判断链表是否为空,直接进行插入,代码tailPointer->next=p,p->next=NULL,tailPointer=p。
3)带头结点和无头结点单链表元素显示方法的区别:区别在于,显示时带头结点是从头结点next开始即p=L->next,而无头结点链表是直接从L开始即p=L。
四、【源程序代码】1) 利用头插法和尾插法建立一个无头结点单链表#include<stdio.h>#include<malloc.h>#include <stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;/* 尾插法*/void creatListTailInsert(LinkList &L, int n){LinkList p, tailPointer;int i;//计数L = (LinkList)malloc(sizeof(LNode));if(!L) exit(0); //分配空间失败则退出程序L = NULL; //no headcrunodetailPointer = L; //把尾赋给尾指针printf("taillist(%d):",n);for(i = 0;i < n; i++){p = (LinkList)malloc(sizeof(LNode));if(!p) exit(0);scanf("%d",&(p->data));if(L == NULL) L = p; //当链表为空,L赋给第一个结点else tailPointer->next = p; //将新结点插入尾部;p->next = NULL;tailPointer = p; //插入的结点变为尾结点}}/* 头插法*/void creatListHeadInsert(LinkList &L, int n){LinkList p;int i;//计数L = (LinkList)malloc(sizeof(LNode));if(!L) exit(0); //分配空间失败则退出程序L = NULL; //no headcrunodeprintf("headlist(%d):",n);for(i = 0;i < n; i++){//创建新结点p = (LinkList)malloc(sizeof(LNode));if(!p) exit(0);scanf("%d",&(p->data));if(L != NULL) p->next = L;else p->next = NULL;L = p; //将头结点next指向赋给新结点}}/* 依次显示表中所有元素*/void getAllElem(LinkList &L, int n){LinkList p;int i = 0;p = L;while(p && i < n){printf("%d ",p->data);p = p->next;i++;}printf("\n");}void main(){LinkList headList;LinkList tailList;int count; //插入元素个数printf("count=");scanf("%d",&count);creatListHeadInsert(headList, count);creatListTailInsert(tailList, count);printf("headList:");getAllElem(headList, count);printf("tailList:");getAllElem(tailList, count);}2) 利用头插法和尾插法建立一个有头结点单链表#include<stdio.h>#include<malloc.h>#include <stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;/* 尾插法*/void creatListTailInsert(LinkList &L, int n){LinkList p, tailPointer;int i;//计数L = (LinkList)malloc(sizeof(LNode));if(!L) exit(0); //分配空间失败则退出程序L->next = NULL; //headcrunodetailPointer = L; //把尾赋给尾指针printf("taillist(%d):",n);for(i = 0;i < n; i++){p = (LinkList)malloc(sizeof(LNode));if(!p) exit(0);scanf("%d",&(p->data));p->next = tailPointer->next;tailPointer->next = p;tailPointer = p; //插入的结点变为尾结点}}/* 头插法*/void creatListHeadInsert(LinkList &L, int n){LinkList p;int i;//计数L = (LinkList)malloc(sizeof(LNode));if(!L) exit(0); //分配空间失败则退出程序L->next = NULL; //headcrunodeprintf("headlist(%d):",n);for(i = 0;i < n; i++){//创建新结点p = (LinkList)malloc(sizeof(LNode));if(!p) exit(0);scanf("%d",&(p->data));p->next = L->next; //将头结点next指向赋给新结点L->next = p;}}/* 依次显示表中所有元素*/void getAllElem(LinkList &L, int n){LinkList p;int i = 0;p = L->next;while(p && i < n){printf("%d ",p->data);p = p->next;i++;}printf("\n");}void main(){LinkList headList;LinkList tailList;int count; //插入元素个数printf("count=");scanf("%d",&count);creatListHeadInsert(headList, count);creatListTailInsert(tailList, count);printf("headList:");getAllElem(headList, count);printf("tailList:");getAllElem(tailList, count);}五、【数据测试】输入:8 //插入8个元素输入八个数字头插法和尾插法区别在于,头插法输入数据是逆序存入,尾插法是顺序存入;带头结点和不带头结点在数据显示上基本没区别,区别在于初始化链表和插入元素时,头指针的操作不同。
1) 利用头插法和尾插法建立一个无头结点单链表2) 利用头插法和尾插法建立一个有头结点单链表。