【14】阶段小结(一)- 线性结构

合集下载

数据结构-线性结构

数据结构-线性结构

数据结构-线性结构数据结构线性结构在计算机科学的世界里,数据结构就像是搭建高楼大厦的基石,为程序的高效运行提供了坚实的基础。

而线性结构,则是众多数据结构中最为基础和常见的一类。

想象一下,你有一堆物品需要整理,你会怎么做?也许你会把它们排成一排,一个接一个,这就是线性结构的基本概念。

简单来说,线性结构中的数据元素按照顺序依次排列,就像排队的人们,每个元素都有唯一的前驱(除了第一个元素)和唯一的后继(除了最后一个元素)。

线性表是线性结构的典型代表。

它可以分为顺序表和链表两种实现方式。

顺序表就像是一排紧密相连的座位,每个座位上都有一个数据元素。

由于这些元素在内存中是连续存储的,所以读取数据非常方便快捷。

但如果要插入或删除元素,就可能需要移动大量的数据,就像在一排坐满人的座位中插入或移除一个人,后面的人都得跟着挪动位置,这会比较费时。

链表则不同,它更像是用链子把一个个数据元素串起来。

每个元素除了存储自身的数据,还包含指向下一个元素的指针。

这样,插入和删除元素就变得相对简单,只需要调整几个指针的指向就行了。

但要访问链表中的某个元素,就需要顺着指针一个一个地找过去,效率相对较低。

栈和队列也是常见的线性结构。

栈就像是一个只能从一端进出的筒子,先进去的元素会被压在下面,后进去的元素在上面,所以取出元素的时候,是后进去的先出来,这就是所谓的“后进先出”原则。

比如,浏览器的后退功能就可以用栈来实现,每次访问新的页面就把当前页面压入栈中,后退时就从栈顶取出之前的页面。

队列则像是排队买票的队伍,先到的先服务,即“先进先出”。

在操作系统的任务调度中,经常会用到队列,新的任务进入队列等待执行,先进入的任务先被处理。

线性结构在日常生活和计算机程序中都有着广泛的应用。

比如,我们在图书馆排队借书,这就是一个队列的例子;我们把要做的事情列成一个清单,这就是一个线性表。

在计算机程序中,线性结构更是无处不在。

当我们处理一组按照特定顺序排列的数据时,线性结构往往是首选。

【14】阶段小结(一)- 线性结构

【14】阶段小结(一)- 线性结构

Chapter2 程序性能
1、简单搜索(查找)算法 简单搜索(查找) – 顺序查找 – 折半查找:针对有序线性表(如数组) 折半查找:针对有序线性表(如数组) 2、简单排序算法:熟练掌握 简单排序算法: – 选择排序 – 冒泡排序 – 插入排序
程序性能(续) 程序性能(
3、程序空间复杂度 – 组成及计算 4、程序时间复杂性分析 – 掌握“操作计数”法估算 掌握“操作计数” 5、渐近符号O、 、Θ 渐近符号O – 使用上述符号准确描述算法的时间复杂度 – 以三种简单排序算法为例
1、数组的两种存储方式: 数组的两种存储方式: - 行主映射 - 列主映射 2、一维数组类:Array1D 一维数组类: 3、二维数组的顺序存储:Array2D 二维数组的顺序存储: 4、矩阵类 – Matrix – 矩阵的基本运算:加、减、乘法 矩阵的基本运算:
数组和矩阵( 数组和矩阵(续)
5、特殊矩阵的压缩 – 对角矩阵 – 三对角矩阵 – 三角矩阵、对称矩阵 三角矩阵、 6、稀疏矩阵 – 两种描述形式:三元组表、十字链表 两种描述形式:三元组表、 – 掌握:SparseMatrix快速转置算法 掌握:SparseMatrix快速转置算法
Chapter3 线性表(数据描述) 线性表(数据描述)
1、线性结构的特点 2、线性表的公式化描述:顺序表 线性表的公式化描述: – 插入、删除、查找等基本操作算法 插入、删除、 – 如何实现内存的有效使用?动态分配一维数组! 如何实现内存的有效使用?动态分配一维数组! 3、线性表的链式描述(链表) 线性表的链式描述(链表) – 插入、删除、查找等基本操作算法 插入、删除、 – 头、尾指针的使用,对算法的影响! 尾指针的使用,对算法的影响!
65 26 91 53 15 31 52 0 1 2 3 4 5 6

数据结构基础知识总结

数据结构基础知识总结

数据结构基础知识总结数据结构是计算机科学中非常重要的一门基础学科,它研究的是不同数据类型之间以及数据元素之间的组织关系和操作方法。

在计算机程序的设计和实现过程中,合理选择和使用数据结构可以提高程序的效率和性能。

本文将总结数据结构的基础知识,包括线性结构、非线性结构和常见的数据结构算法。

一、线性结构线性结构是指数据元素之间存在着一对一的前驱和后继关系。

常见的线性结构有顺序表、链表和栈。

1. 顺序表顺序表是一种用一组连续的存储单元依次存储线性排列的数据元素的结构。

其特点是可以随机访问元素,但插入和删除操作较慢。

2. 链表链表是一种用一组不连续的存储单元存储线性排列的数据元素的结构。

链表的插入和删除操作较快,但访问元素需要遍历链表。

3. 栈栈是一种先进后出的线性结构。

它有两个基本操作:入栈和出栈。

栈可以用数组或链表实现。

二、非线性结构非线性结构是指数据元素之间存在多对多的关系,常见的非线性结构有树和图。

1. 树树是一种由n(n>=1)个有限节点组成的集合,它满足以下条件:有且只有一个特定的节点被称为根节点,除根节点外的其余节点被分成m(m>=0)个互不相交的有限集,每个集合本身又是一个树。

树的常见应用有文件系统、数据库索引等。

2. 图图是由顶点的有限非空集合和顶点之间的边的集合组成。

图可以分为有向图和无向图,顶点之间的关系可以是一对一、一对多或多对多。

图的常见应用有社交网络、路由算法等。

三、常见的数据结构算法1. 查找算法查找算法用于在给定的数据集合中找到满足特定条件的数据元素。

常见的查找算法有顺序查找、二分查找和哈希查找。

2. 排序算法排序算法用于将给定的数据集合按照特定的规则进行排序。

常见的排序算法有冒泡排序、插入排序、选择排序、快速排序和归并排序。

3. 树的遍历算法树的遍历算法用于按照特定顺序访问树中的所有节点。

常见的树的遍历算法有前序遍历、中序遍历和后序遍历。

总结:数据结构是计算机程序设计中非常重要的一部分。

数据结构自学总结(1)线性结构

数据结构自学总结(1)线性结构

数据结构自学总结--第一阶段线性结构一.数据结构概论1.1 时间复杂度:程序执行的次数T = O(n);1.2 空间复杂度:出现执行时所占用的内存空间;1.3数据结构的定义:狭义:是专门研究数据存储的问题数据的存储包含两方面:个体的存储+个体关系的存储广义:数据结构即包含数据的存储也包含数据的操作对存储数据的操作就是算法1.4算法的定义:是对存储数据的操作狭义的算法是与数据的存储方式密切相关广义的算法是与数据的存储方式无关泛型:利用某种技术达到的效果就是:不同的存储方式,执行的操作是一样的。

1.5 利用结构体定义自己的数据类型typedef struct Student{int sid;char name[100];char sex;}* PST,STU; //PST 等于struct student * ,STU代表了struct Student二.线性结构2.1连续存储(顺序表,数组):元素类型相同,大小相等优点:存取速度很快缺点:实现必须知道数组的长度需要大块连续的内存快插入删除元素的效率极低空间通常是有限的2.2离散存储(链表)优点:空间没有限制插入删除元素很快缺点:存取速度很慢定义:n个节点离散分配彼此通过指针相连每个节点只有一个前驱节点,每个节点只有一个后续节点首节点没有前驱节点尾节点没有后续节点专业术语:首节点:第一个有效节点尾节点:最后一个有效节点头结点:第一个有效节点之前的那个节点,头结点并不存放有效数据,加头节点是为了方便对链表的操作,头结点的数据类型和首节点的数据类型一样头指针:指向头结点的指针变量尾指针:指向尾节点的指针变量如何确定一个链表需要几个参数?如果希望通过一个函数来对链表进行处理,我们至少要接受链表的哪些参数的问题只需要一个参数:头指针,因为通过头指针可以推算出链表的所有信息一个节点的生成:struct Node{int data;//数据域struct Node * pNext; //指针域}Node,*PNode; //Node等价于Struct Node,PNode等价于Struct NOde *类型2.3链表的分类:单链表:双链表:每一个节点有两个指针域循环链表:能通过任何一个节点找到其他所有的结点非循环链表:算法:遍历查找清空销毁求长度排序删除节点:r=p->pNext ; p->pNext = q; q->pNext = r;或者是q->pNext = p->pNext; p->pNext = q注意:p->pNext 表示p指向的那个节点的pNext成员插入节点3 各种数据结构的实现算法以及相关操作方法的实现3.1 实现顺序表的各种基本运算/*2012年2月20日22:32:41目的:实现顺序表中常用的9个操作方法,并实现测试之*/#include <stdio.h>#include <malloc.h>#define MaxSize 50typedef char ElemType;typedef struct{ElemType data[MaxSize];int length;} SqList;extern void InitList(SqList *&L); //形参的改变映射给实参extern void DestroyList(SqList *L);extern int ListEmpty(SqList *L);extern int ListLength(SqList *L);extern void DispList(SqList *L);extern int GetElem(SqList *L,int i,ElemType &e);extern int LocateElem(SqList *L, ElemType e);extern int ListInsert(SqList *&L,int i,ElemType e);extern int ListDelete(SqList *&L,int i,ElemType &e);int main(void){SqList *L;ElemType e;printf("\n=============顺序表中所有方法的实现===================\n"); printf(" (1)初始化顺序表L\n");InitList(L);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");ListInsert(L,1,'a');ListInsert(L,2,'b');ListInsert(L,3,'c');ListInsert(L,4,'d');ListInsert(L,5,'e');printf(" (3)输出顺序表L:");DispList(L);printf(" (4)顺序表L长度=%d\n",ListLength(L));printf(" (5)顺序表L为%s\n",(ListEmpty(L)?"空":"非空"));GetElem(L,3,e);printf(" (6)顺序表L的第3个元素=%c\n",e);printf(" (7)元素a的位置=%d\n",LocateElem(L,'a'));printf(" (8)在第4个元素位置上插入f元素\n");ListInsert(L,4,'f');printf(" (9)输出顺序表L:");DispList(L);printf(" (10)删除L的第3个元素\n");ListDelete(L,3,e);printf(" (11)输出顺序表L:");DispList(L);printf(" (12)释放顺序表L\n");DestroyList(L);return 0;}void InitList(SqList *&L){L=(SqList *)malloc(sizeof(SqList));L->length=0;}void DestroyList(SqList *L){free(L);}int ListEmpty(SqList *L){return(L->length==0);}int ListLength(SqList *L){return(L->length);}void DispList(SqList *L){int i;if (ListEmpty(L)) return;for (i=0;i<L->length;i++)printf(" %c ",L->data[i]);printf("\n");}int GetElem(SqList *L,int i,ElemType &e) {if (i<1 || i>L->length)return 0;e=L->data[i-1];return 1;}int LocateElem(SqList *L, ElemType e){int i=0;while (i<L->length && L->data[i]!=e) i++; if (i>=L->length)return 0;elsereturn i+1;}int ListInsert(SqList *&L,int i,ElemType e)int j;if (i<1 || i>L->length+1)return 0;i--; //将顺序表位序转化为elem下标*/ for (j=L->length;j>i;j--) //将data[i]及后面元素后移一个位置*/ L->data[j]=L->data[j-1];L->data[i]=e;L->length++; //顺序表长度增1*/return 1;}int ListDelete(SqList *&L,int i,ElemType &e){int j;if (i<1 || i>L->length)return 0;i--; //将顺序表位序转化为elem下标*/ e=L->data[i];for (j=i;j<L->length-1;j++)L->data[j]=L->data[j+1];L->length--;return 1;}/*在VC++6.0中的输出结果为:=============顺序表中所有方法的实现===================(1)初始化顺序表L(2)依次采用尾插法插入a,b,c,d,e元素(3)输出顺序表L: a b c d e(4)顺序表L长度=5(5)顺序表L为非空(6)顺序表L的第3个元素=c(7)元素a的位置=1(8)在第4个元素位置上插入f元素(9)输出顺序表L: a b c f d e(10)删除L的第3个元素(11)输出顺序表L: a b f d e(12)释放顺序表LPress any key to continue总结:当调用DestroyList(L)后,free释放的事L指向的内存空间,但是此时,指针变量L仍然存在3.2 实现单链表的各种基本运算/*2012年2月22日19:05:12 作者:陈金林目的:实现单链表的基本方法,并实现之*/#include <stdio.h>#include <malloc.h>#define MaxSize 50typedef char ElemType;typedef struct LNode{ElemType data;struct LNode * next;}LinkList;void InitList(LinkList * &L);int ListInsert(LinkList * &L,int i,ElemType e);void DispList(LinkList * L);int ListLength(LinkList * L);int ListEmpty(LinkList * L);int GetElem(LinkList * L,int i,ElemType &e);int LocateElem(LinkList * L,ElemType e);int ListDelete(LinkList * &L,int i,ElemType &e);void DestroyList(LinkList * &L);int main(void){LinkList * h;ElemType e;printf("\n================实现单链表的常用操作============\n");printf("(1)初始化单链表h\n");InitList(h);printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");ListInsert(h,1,'a');ListInsert(h,2,'b');ListInsert(h,3,'c');ListInsert(h,4,'d');ListInsert(h,5,'e');printf("(3)输出单链表h");DispList(h);printf("(4)输出单链表h长度%d\n",ListLength(h));printf("(5)判断单链表h是否为空%s\n",(ListEmpty(h)==0)?"空":"非空"); GetElem(h,3,e);printf("(6)输出单链表h的第三个元素%d\n",e);printf("(7)输出元素'a'的位置%d\n",LocateElem(h,'a'));printf("(8)在第四个元素位置上插入'f'元素\n");ListInsert(h,4,'f');printf("(9)输出单链表h");DispList(h);printf("(10)删除h的第3个元素\n");ListDelete(h,3,e);printf("(11)输出单链表h :");DispList(h);printf("(12)释放单链表h\n");DestroyList(h);return 0;}void InitList(LinkList * &L){L = (LinkList *)malloc(sizeof(LinkList));L->next = NULL;}int ListInsert(LinkList * &L,int i,ElemType e){int j = 0;LinkList * p = L,* s;while(j<i-1 && p!=NULL){j++;p = p->next;}if(p == NULL)return 0;else{s = (LinkList *)malloc(sizeof(LinkList));s->data = e;s->next = p->next;p->next = s;return 1;}}void DispList(LinkList * L){LinkList * p = L->next;while(p!=NULL){printf(" %c ",p->data);p = p->next;}printf("\n");}int ListLength(LinkList * L){LinkList * p = L;int n = 0;while(p->next!=NULL){n++;p = p->next;}return(n);}int ListEmpty(LinkList * L){return (L->next == NULL);}int GetElem(LinkList * L,int i,ElemType &e) {int j = 0;LinkList * p = L;while(j<i && p!=NULL){j++;p = p->next;}if(p == NULL)return 0;else{e = p->data;return 1;}}int LocateElem(LinkList * L,ElemType e){LinkList * p = L->next;int i = 1;while(p!=NULL && p->data!=e){p = p->next;i++;}if(p == NULL)return (0);elsereturn (i);}int ListDelete(LinkList * &L,int i,ElemType &e) {int j= 0;LinkList * p = L,*q;while(j<i-1 && p!=NULL){j++;p = p->next;}if(p == NULL)return 0;else{q = p->next;if(q==NULL)return 0;e = q->data;p->next = q->next;free(q);return 1;}}void DestroyList(LinkList * &L){LinkList * p =L,* q=p->next;while(q!=NULL){free(p);p = q;q = p->next;}free(q);}/*在VC++6.0中的输出结果为:=======================实现单链表的常用操作=================(1)初始化单链表h(2)依次采用尾插法插入a,b,c,d,e元素(3)输出单链表h a b c d e(4)输出单链表h长度5(5)判断单链表h是否为空空(6)输出单链表h的第三个元素99(7)输出元素'a'的位置1(8)在第四个元素位置上插入'f'元素(9)输出单链表h a b c f d e(10)删除h的第3个元素(11)输出单链表h : a b f d e(12)释放单链表hPress any key to continue*/3.3 实现双链表的各种基本运算#include <stdio.h>#include <malloc.h>#define MaxSize 50typedef char ElemType;typedef struct DNode{ElemType data;struct DNode * prior;struct DNode * next;} DLinkList;extern void InitList(DLinkList *&L); //以下均为外部函数extern void DestroyList(DLinkList *&L);extern int ListEmpty(DLinkList *L);extern int ListLength(DLinkList *L);extern void DispList(DLinkList *L);extern int GetElem(DLinkList *L,int i,ElemType &e);extern int LocateElem(DLinkList *L,ElemType e);extern int ListInsert(DLinkList *&L,int i,ElemType e);extern int ListDelete(DLinkList *&L,int i,ElemType &e);int main(void){DLinkList * h;ElemType e;printf("\n========双链表所有操作方法的实现====作者:陈金林======\n");printf("(1)初始化双链表h\n");InitList(h);printf("(2)依次采用尾插法插入a,b,c,d,e元素\n");ListInsert(h,1,'a');ListInsert(h,1,'b');ListInsert(h,1,'c');ListInsert(h,1,'d');ListInsert(h,1,'e');printf("(3)输出双链表h :");DispList(h);printf("(4)输出双链表h的长度%d\n",ListLength(h));printf("(5)双链表h为%s\n",(ListEmpty(h)?"空":"非空"));GetElem(h,3,e);printf("(6)输出双链表h的第3个元素%c\n",e);printf("(7)输出元素'a'的位置%d\n",LocateElem(h,'a'));printf("(8)在第4个元素的位置上插入'f'元素\n");printf("(9)输出双链表h:");DispList(h);printf("(10)删除h的第三个元素\n");ListDelete(h,3,e);printf("(11)输出双链表h:");DispList(h);printf("(12)释放双链表h\n");DestroyList(h);return 0;}void InitList(DLinkList *&L){L=(DLinkList *)malloc(sizeof(DLinkList)); //创建头结点L->prior=L->next=NULL;}void DestroyList(DLinkList *&L){DLinkList *p=L,*q=p->next;while (q!=NULL){free(p);p=q;q=p->next;}free(p);}int ListEmpty(DLinkList *L){return(L->next==NULL);}int ListLength(DLinkList *L){DLinkList *p=L;int i=0;while (p->next!=NULL){i++;p=p->next;}return(i);}void DispList(DLinkList *L){DLinkList *p=L->next;while (p!=NULL){printf(" %c ",p->data);p=p->next;}printf("\n");}int GetElem(DLinkList *L,int i,ElemType &e) {int j=0;DLinkList *p=L;while (j<i && p!=NULL){j++;p=p->next;}if (p==NULL)return 0;else{e=p->data;return 1;}}int LocateElem(DLinkList *L,ElemType e){int n=1;DLinkList *p=L->next;while (p!=NULL && p->data!=e){n++;p=p->next;}if (p==NULL)return(0);elsereturn(n);}int ListInsert(DLinkList *&L,int i,ElemType e){int j=0;DLinkList *p=L,*s;while (j<i-1 && p!=NULL){j++;p=p->next;}if (p==NULL) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{s=(DLinkList *)malloc(sizeof(DLinkList)); //创建新结点*ss->data=e;s->next=p->next; //将*s插入到*p之后if (p->next!=NULL) p->next->prior=s;s->prior=p;p->next=s;return 1;}}int ListDelete(DLinkList *&L,int i,ElemType &e){int j=0;DLinkList *p=L,*q;while (j<i-1 && p!=NULL){j++;p=p->next;}if (p==NULL) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{q=p->next; //q指向要删除的结点if (q==NULL) return 0; //不存在第i个结点e=q->data;p->next=q->next; //从单链表中删除*q结点if (p->next!=NULL) p->next->prior=p;free(q); //释放*q结点return 1;}}3.4 实现循环单链表的各种基本运算/*2012年2月24日20:57:59 作者:陈金林目的:循环单链表所有方法的实现*/#include <stdio.h>#include <malloc.h>typedef char ElemType;typedef struct LNode //定义循环单链表结点类型{ElemType data;struct LNode *next;} LinkList;void InitList(LinkList *&L);void DestroyList(LinkList *&L);int ListEmpty(LinkList *L);int ListLength(LinkList *L);void DispList(LinkList *L);int GetElem(LinkList *L,int i,ElemType &e);int LocateElem(LinkList *L,ElemType e);int ListInsert(LinkList *&L,int i,ElemType e);int ListDelete(LinkList *&L,int i,ElemType &e);int main(void){LinkList * h;ElemType e;printf("\n==========循环单链表所有方法的实现=====================\n"); printf(" (1)初始化循环单链表h\n");InitList(h);printf(" (2)依次采用头插法插入a,b,c,d,e元素\n");ListInsert(h,1,'a');ListInsert(h,1,'b');ListInsert(h,1,'c');ListInsert(h,1,'d');ListInsert(h,1,'e');printf(" (3)输出循环单链表h:");DispList(h);printf(" (4)输出循环单链表h长度length = %d\n",ListLength(h));printf(" (5)判断循环单链表h是否为空? %s\n",ListEmpty(h)?"空":"非空"); GetElem(h,3,e);printf(" (6)输出循环单链表h的第3个元素%c\n",e);printf(" (7)输出元素'a'的位置:%d\n",LocateElem(h,'a'));printf(" (8)在第四个元素位置上插入'f'元素\n");ListInsert(h,4,'f');printf(" (9)输出循环单链表h :");DispList(h);printf(" (10)删除L的第3个元素\n");ListDelete(h,3,e);printf(" (11)输出循环单链表h :");DispList(h);printf(" (12)释放循环单链表h\n");DestroyList(h);return 0;}void InitList(LinkList *&L){L=(LinkList *)malloc(sizeof(LinkList)); //创建头结点L->next=L; //说名此链表为循环单链表}void DestroyList(LinkList *&L){LinkList *p=L,*q=p->next;while (q!=L){free(p);p=q;q=p->next;}free(p);}int ListEmpty(LinkList *L){return(L->next==L);}int ListLength(LinkList *L){LinkList *p=L;int i=0;while (p->next!=L){i++;p=p->next;}return(i);}void DispList(LinkList *L){LinkList *p=L->next;while (p!=L){printf(" %c ",p->data);p=p->next;}printf("\n");}int GetElem(LinkList *L,int i,ElemType &e){int j=0;LinkList *p;if (L->next!=L) //单链表不为空表时{if (i==1){e=L->next->data;return 1;}else //i不为1时{p=L->next;while (j<i-1 && p!=L){j++;p=p->next;}if (p==L)return 0;else{e=p->data;return 1;}}}else //单链表为空表时return 0;}int LocateElem(LinkList *L,ElemType e) {LinkList *p=L->next;int n=1;while (p!=L && p->data!=e){p=p->next;n++;}if (p==L)return(0);elsereturn(n);}int ListInsert(LinkList *&L,int i,ElemType e) {int j=0;LinkList *p=L,*s;if (p->next==L || i==1) //原单链表为空表或i==1时{s=(LinkList *)malloc(sizeof(LinkList));//创建新结点*ss->data=e;s->next=p->next; //将*s插入到*p之后p->next=s;return 1;}else{p=L->next;while (j<i-2 && p!=L){j++;p=p->next;}if (p==L) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{s=(LinkList *)malloc(sizeof(LinkList));//创建新结点*ss->data=e;s->next=p->next; //将*s插入到*p之后p->next=s;return 1;}}}int ListDelete(LinkList *&L,int i,ElemType &e){int j=0;LinkList *p=L,*q;if (p->next!=L) //原单链表不为空表时{if (i==1) //i==1时{q=L->next; //删除第1个结点e=q->data;L->next=q->next;free(q);return 1;}else //i不为1时{p=L->next;while (j<i-2 && p!=L){j++;p=p->next;}if (p==L) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{q=p->next; //q指向要删除的结点e=q->data;p->next=q->next; //从单链表中删除*q结点free(q); //释放*q结点return 1;}}}else return 0;}/*在VC++6.0中的输出结果为:=================循环单链表所有方法的实现=====================(1)初始化循环单链表h(2)依次采用头插法插入a,b,c,d,e元素(3)输出循环单链表h: e d c b a(4)输出循环单链表h长度length = 5(5)判断循环单链表h是否为空? 非空(6)输出循环单链表h的第3个元素c(7)输出元素'a'的位置:5(8)在第四个元素位置上插入'f'元素(9)输出循环单链表h : e d c f b a(10)删除L的第3个元素(11)输出循环单链表h : e d f b a(12)释放循环单链表hPress any key to continue*/3.5 实现循环双链表的各种基本运算/*2012年2月24日21:01:46 作者:陈金林目的:循环双链表所有方法的实现*/#include <stdio.h>#include <malloc.h>typedef char ElemType;typedef struct DNode //定义双链表结点类型{ElemType data;struct DNode *prior; //指向前驱结点struct DNode *next; //指向后继结点} DLinkList;void InitList(DLinkList *&L);void DestroyList(DLinkList *&L);int ListEmpty(DLinkList *L);int ListLength(DLinkList *L);void DispList(DLinkList *L);int GetElem(DLinkList *L,int i,ElemType &e);int LocateElem(DLinkList *L,ElemType e);int ListInsert(DLinkList *&L,int i,ElemType e);int ListDelete(DLinkList *&L,int i,ElemType &e);int main(void){DLinkList * h;ElemType e;printf("\n=================循环双链表所有方法的实现=====================\n");printf(" (1)初始化循环双链表h\n");InitList(h);printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");ListInsert(h,1,'a');ListInsert(h,1,'b');ListInsert(h,1,'c');ListInsert(h,1,'d');ListInsert(h,1,'e');printf(" (3)输出循环双链表h:");DispList(h);printf(" (4)输出循环双链表h长度length = %d\n",ListLength(h));printf(" (5)判断循环双链表h是否为空? %s\n",ListEmpty(h)?"空":"非空");GetElem(h,3,e);printf(" (6)输出循环双链表h的第3个元素%c\n",e);printf(" (7)输出元素'a'的位置:%d\n",LocateElem(h,'a'));printf(" (8)在第四个元素位置上插入'f'元素\n");ListInsert(h,4,'f');printf(" (9)输出循环双链表h :");DispList(h);printf(" (10)删除L的第3个元素\n");ListDelete(h,3,e);printf(" (11)输出循环双链表h :");DispList(h);printf(" (12)释放循环双链表h\n");DestroyList(h);return 0;}void InitList(DLinkList *&L){L=(DLinkList *)malloc(sizeof(DLinkList)); //创建头结点L->prior=L->next=L;}void DestroyList(DLinkList *&L){DLinkList *p=L,*q=p->next;while (q!=L){free(p);p=q;q=p->next;}free(p);}int ListEmpty(DLinkList *L){return(L->next==L);}int ListLength(DLinkList *L){DLinkList *p=L;int i=0;while (p->next!=L){i++;p=p->next;}return(i);}void DispList(DLinkList *L){DLinkList *p=L->next;while (p!=L){printf(" %c ",p->data);p=p->next;}printf("\n");}int GetElem(DLinkList *L,int i,ElemType &e) {int j=0;DLinkList *p;if (L->next!=L) //双链表不为空表时{if (i==1){e=L->next->data;return 1;}else //i不为1时{p=L->next;while (j<i-1 && p!=L){j++;p=p->next;}if (p==L)return 0;else{e=p->data;return 1;}}}else //双链表为空表时return 0;}int LocateElem(DLinkList *L,ElemType e) {int n=1;DLinkList *p=L->next;while (p!=NULL && p->data!=e){n++;p=p->next;}if (p==NULL)return(0);elsereturn(n);}int ListInsert(DLinkList *&L,int i,ElemType e){int j=0;DLinkList *p=L,*s;if (p->next==L) //原双链表为空表时{s=(DLinkList *)malloc(sizeof(DLinkList)); //创建新结点*ss->data=e;p->next=s;s->next=p;p->prior=s;s->prior=p;return 1;}else if (i==1) //原双链表不为空表但i=1时{s=(DLinkList *)malloc(sizeof(DLinkList)); //创建新结点*ss->data=e;s->next=p->next;p->next=s; //将*s插入到*p之后s->next->prior=s;s->prior=p;return 1;}else{p=L->next;while (j<i-2 && p!=L){ j++;p=p->next;}if (p==L) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{s=(DLinkList *)malloc(sizeof(DLinkList)); //创建新结点*ss->data=e;s->next=p->next; //将*s插入到*p之后if (p->next!=NULL) p->next->prior=s;s->prior=p;p->next=s;return 1;}}}int ListDelete(DLinkList *&L,int i,ElemType &e){int j=0;DLinkList *p=L,*q;if (p->next!=L) //原双链表不为空表时{if (i==1) //i==1时{q=L->next; //删除第1个结点e=q->data;L->next=q->next;q->next->prior=L;free(q);return 1;}else //i不为1时{p=L->next;while (j<i-2 && p!=NULL){j++;p=p->next;}if (p==NULL) //未找到第i-1个结点return 0;else //找到第i-1个结点*p{q=p->next; //q指向要删除的结点if (q==NULL) return 0; //不存在第i个结点e=q->data;p->next=q->next; //从单链表中删除*q结点if (p->next!=NULL) p->next->prior=p;free(q); //释放*q结点return 1;}}}else return 0; //原双链表为空表时}/*在VC++6.0中的输出结果为:=================循环双链表所有方法的实现=====================(1)初始化循环双链表h(2)依次采用尾插法插入a,b,c,d,e元素(3)输出循环双链表h: e d c b a(4)输出循环双链表h长度length = 5(5)判断循环双链表h是否为空? 非空(6)输出循环双链表h的第3个元素c(7)输出元素'a'的位置:5(8)在第四个元素位置上插入'f'元素(9)输出循环双链表h : e d c f b a(10)删除L的第3个元素(11)输出循环双链表h : e d f b a(12)释放循环双链表hPress any key to continue*/三.线性结构的常见应用之一------------------栈定义:一种可以实现'先进后出' 的存储结构。

线性结构

线性结构
a1 a2 an NIL
空表时:L=NIL 空表时:
2.3 线性表的链式存储结构
struct node { elemtype data; struct node* next; }; node为一记录,它由data和next两项组成; 为一记录,它由 为一记录 和 两项组成; next为一指针,指向node记录类型; 为一指针,指向 记录类型; 为一指针 记录类型 为数据域; data为数据域; 为数据域
2.3 线性表的链式存储结构
2. 带头结点的线性链表 . 在线性链表的第一个元素结点之前附设一个结点 称头结点),它的数据域不存储任何信息, ),它的数据域不存储任何信息 (称头结点),它的数据域不存储任何信息,其指针 域存储第一个元素结点的存储位置。头指针L指向该 域存储第一个元素结点的存储位置。头指针 指向该 头结点。 头结点。 空表时: ↑ 空表时:L↑.next=NIL 带头结点链表的引入是为了使算法判空和处理一致。 带头结点链表的引入是为了使算法判空和处理一致
2.2 线性表的顺序存储结构
插入算法时间复杂度分析: 插入算法时间复杂度分析: 最坏情况是在第1 最坏情况是在第1个元素前插入 (i=1), (i=1), 此时,要后移n个元素,因此, 此时,要后移n个元素,因此,
T(n)=O(n) =O(DELETE( 2. 删除运算DELETE(L,i)
2.3 线性表的链式存储结构
初始化算法:
elemtype initlist(node * * h) { *h=(node *)malloc(sizeof(node)); (*h)->next=null; }
2.3 线性表的链式存储结构
3. 几种基本运算在单链表上的实现 . (1)GET(L,i)函数

数据结构实验报告1-线性结构的顺序存储

数据结构实验报告1-线性结构的顺序存储
评定等级为:优秀、良好、中等、及格、不及格
教师签名: 2008 年 月 日
第2页共2页
2、参照课本,定义一个向量类模板,编写它的成员函数模板,对类模板加以实现;编写向量的并、 交运算功能函数;编写主程序,对两个向量进行分别进行合并、交运算。
3、通过阅读课本栈类板代码,理解栈类操作特点;编写一个借助于栈,将二进制数转换为十进制数 字串的程序;编写汉诺塔问题程序,理解函数的递归调用。
4、参照课本,定义一个顺序队列类模板,编写它的成员函数模板 ,对类模板加以实现;编写主程序, 对队列进行各种基本操作,理解队列的操作特性。
五、 实验总结(包括心得体会、问题回答及实验改进意见,可附页)
通过本次实验,基本上能够理解线性结构的顺序存储方式及各种不同线性结构的操作方式;顺序存 储方式主要用于线性的数据结构,它把逻辑上相邻的数据元素存储在物理上相邻的存储单元里结点之间 的关系由存储单元的邻接关系来体现。线性表、向量、栈、队列都属于线性结构的顺序存储,各结点的 物理地址是相邻的,每一次插入、删除运算会引起相应结点物理地址的重新排列;栈的操作特点是先进 后出,而队列的操作特点是先进先出。
2、 对两个向量进行合并、交运算,结果如下: 输入向量 La 的结点元素:1 2 3 4 5,输入 Lb 的结点元素:1 2 3 4 5 6,则两向量的交集为:1 2 3 4 5;并集为:1 2 3 4 5 6。
3、(1)将二进制数转换为十进制数字串的程序,结果如下: 输入要转换的带符号整数 x:+3;则 x 转换成十进制数字串输出为:+3
Байду номын сангаас
第1页共2页
四、 实验结果(包括程序或图表、结论陈述、数据记录及分析等,可附页)
1、 对线性表进行插入、删除、定位等操作,结果如下: 输入线性表元素:1 2 3 4 5,(1)选择插入,输入插入位置 2,插入值 9,则新的线性表为:1 2 9 3 4 5;(2)选择删除,输入删除元素序号 5,则新的线性表为:1 2 9 3 4;(3)选择取值,输入要求 值元素序号 2,则屏幕输出:第2个元素的值为 9;(4)选择查找,输入要查找的元素值 9,则屏幕输 出:要查找元素的序号为 2。

数据结构-线性结构

数据结构-线性结构

数据结构-线性结构线性表线性表是最简单最常见的数据结构,属于逻辑结构;线性表有两种实现⽅式(存储⽅式),分别是顺序实现和链接实现;定义:线性表是由n(>=0)个数据元素组成的有限序列,数据元素的个数n定义为表的长度;术语:前驱, 后继, 直接前驱, 直接后继, 长度, 空表案例:线性表⽤L表⽰,⼀个⾮空线性表可记为L = (a1,a2,..an);a1后⾯的称为a1的后继an前⾯的称为an的前驱a1为起始节点,an为终端节点,任意相邻的两个元素,如a1和a2,a1是a2的直接前驱,a2是a1的直接后继;线性表中元素个数即表的长度,此处为n;表中没有任何元素时,称为空表除了⾸节点和尾节点之外,每个节点都有且只有⼀个直接前驱和直接后继,⾸节点没有前驱,尾节点没有后继;节点之间的关系属于⼀对⼀;线性表的基本运算初始化Initiate(L) 建⽴⼀个空表L(),L不包含数据元素求表长度Length(L) 返回线性表的长度取表元素Get(L,i) 返回线性表的第i个元素,i不满⾜1<=i<=Length(L)时,返回特殊值;定位Locate(L,x)查找x在L中的节点序号,若有多个匹配的返回第⼀个,若没有匹配的返回0;插⼊Insert(L,x,i)将x插⼊到L的第i个元素的前⾯(其他元素往后挪),参数i取值范围为1<=i<=Length(L)+1;运算结束后表长度+1;删除Delete(L,i)删除表L中的第i个元素,i有效范围1<=i<=Length(L);操作结束后表长度-1强调:上述的第i个指的是元素的序号从1开始,⽽不是下标从0开始;另外:插⼊操作要保证操作后数据还是⼀个接着⼀个的不能出现空缺;线性表的顺序存储实现线性表是⼀种逻辑结构,可以通过顺序存储结构来实现,即:将表中的节点⼀次存放在计算机内存中⼀组连续的存储单元中,数据元素在线性表中的邻接关系决定了它们在存储空间中的存储位置;换句话说逻辑结构中相邻的两个节点的实际存储位置也相邻;⽤顺序存储结构实现的线性表也称之为为顺序表,⼀般采⽤数组来实现;图⽰:⼤⼩与长度:线性表的⼤⼩:指的是最⼤能存储的元素个数线性表的长度:指的是当前已存储的个数⽰例:c语⾔实现:#include <stdio.h>//初始化操作:const MAX_SIZE = 5;//最⼤长度typedef struct list {int data[MAX_SIZE];//数组int length;//当前数据长度};//获取targert在表中的位置int locate(struct list *l,int target){for (int i = 0;i < l->length;i++){if (target == l->data[i]){return i + 1;}}return 0;}//获取第loc个元素int get(struct list *l,int loc){if (loc < 1 || loc > l->length){printf("error:位置超出范围\n");return -1;}else{return l->data[loc-1];}}//插⼊⼀个元素到第loc个位置上void insert(struct list *l,int data,int location){if (l->length == MAX_SIZE){printf("errolr:表容量已满\n");return;}if (location < 1 || location > l->length+1){printf("error:位置超出范围\n");return;}//⽬标位置后⾯的内容以此往后挪for (int i = l->length; i >= location; i--) {l->data[i] = l->data[i-1];}//在⽬标位置放⼊新的数据l->data[location-1] = data;l->length+=1;//长度加1}//删除第loc个元素,从⽬标位置往后的元素⼀次向前移动void delete(struct list *l,int loc){if (loc < 1|| loc > l->length){printf("error:位置超出范围\n");return;}//⽬标位置及后⾯的所有元素全部向后移动for (;loc < l->length; ++loc) {l->data[loc-1] = l->data[loc];}l->length-=1;}//打印所有元素测试⽤void show(struct list l){for (int i = 0; i < l.length; ++i) {printf("%d\n",l.data[i]);}}//测试int main() {struct list alist = {};insert(&alist,100,alist.length+1);insert(&alist,200,alist.length+1);insert(&alist,300,alist.length+1);insert(&alist,400,alist.length+1);delete(&alist,1);printf("%d\n",alist.length);show(alist);printf("%d\n",get(&alist,4));printf("%d\n", locate(&alist,300));printf("%d\n", get(&alist,1));return 0;}插⼊算法分析:假设线性表中含有n个元素,在插⼊元素时,有n+1个位置可以插⼊,因为要保证数据是连续的每个位置插⼊数据的概率是: 1/(n+1)在i的位置插⼊时,要移动的元素个数为:n - i + 1算法时间复杂度为:O(n)删除算法分析:假设线性表中含有n个元素,在删除元素时,有n个位置可以删除每个位置插⼊数据的概率是: 1/n在i的位置删除时,要移动的元素个数为:n - i算法时间复杂度为:O(n)插⼊与删除的不⾜顺序表在进⾏插⼊和删除操作时,平均要移动⼤约⼀半的数据元素,当存储的数据量⾮常⼤的时候,这⼀点需要特别注意;简单的说,顺序表在插⼊和删除时的效率是不够好的;特别在数据量⼤的情况下;顺序表总结:1.顺序表是⼀维数组实现的线性表2.逻辑上相邻的元素,在存储结构中也是相邻的3.顺序表可实现随机读取优缺点:优点:⽆需为了表⽰元素直接的逻辑关系⽽增加额外的存储空间可⽅便的随机存取表中的任⼀节点缺点:插⼊和删除运算不⽅便,需要移动⼤量的节点顺序表要求占⽤连续的存储空间,必须预先分配内存,因此当表中长度变化较⼤时,难以确定合适的存储空间⼤⼩;顺序表节点存储地址计算:设第i个节点的存储地址为x设顺序表起始地址为loc,每个数据元素占L个存储单位计算公式为:x = loc + L * (i-1)如 loc = 100 i = 5 L = 4 则 x = 116线性表的链接存储实现线性表也可通过链接存储⽅式来实现,⽤链接存储⽅式实现的线性表也称为链表 Link List链式存储结构:1.可⽤任意⼀组存储单元来存储数据2.链表中节点的逻辑次序与物理次序不⼀定相同3.每个节点必须存储其后继节点的地址信息(指针)图⽰:单链表单链表指的是只能沿⼀个⽅向查找数据的链表,如上图每个节点由两个部分(也称为域)组成data域存放节点值得数据域next域存放节点的直接后继的地址的指针域(也称为链域)节点结构:每个节点只知道⾃⼰后⾯⼀个节点却不知道⾃⼰前⾯的节点所以称为单链表图⽰:带有head节点的单链表:单链表的第⼀个节点通常不存储数据,称为头指针,使⽤头指针来存储该节点的地址信息,之所以这么设计是为了⽅便运算;单链表特点:其实节点也称为⾸节点,没有前驱,所以头指针要指向该节点,以保证能够访问到起始节点;头指针可以唯⼀确定⼀个链表,单链表可以使⽤头指针的名称来命名;终端节点也称尾节点,没有后继节点,所以终端节点的next域为NULL;除头结点之外的⼏点称为表结点为⽅便运算,头结点中不存储数据单链表数据结构定义//数据结构定义typedef struct node {struct node *next;int data,length;} Node, *LinkList;/** typedef 是⽤来取别名的* Node 是struct node 的别名* *LinkList 是 struct node *的别名* 后续使⽤就不⽤在写struct关键字了*/运算:初始化⼀个空链表有⼀个头指针和⼀个头结点构成假设已定义指针变量L,使L指向⼀个头结点,并使头结点的next为NULL//时间复杂度 :O(1)LinkList initialLinkList() {// 定义链表的头结点LinkList head;//申请空间head = malloc(sizeof(struct node));//使头结点指向NULLhead->next = NULL;return head;}求表长从头指针开始遍历每个节点知道某个节点next为NULL为⽌,next不为空则个数len+1;//求表长时间复杂度 :O(n)int length(LinkList list){int len = 0;Node *c = list->next;while(c != NULL){len+=1;c = c->next;}return len;}读表元素给定⼀个位置n,获取该位置的节点遍历链表,过程中若某节点next为NULL或已遍历个数index=n则结束循环//从链表中获取第position个位置的节点时间复杂度 :O(n)Node *get(LinkList list, int position) {Node *current;int index = 1;current = list->next;//如果下⾯还有值并且还没有到达指定的位置就继续遍历要和查找元素区别开这就是⼀直往后遍历直到位置匹配就⾏了 while (current != NULL && index < position) {current = current->next;index += 1;}if (index == position) {return current;}return NULL;}定位对给定表元素的值,找出这个元素的位置遍历链表,若某节点数据域与要查找的元素data相等则返回当前遍历的次数index//求表head中第⼀个值等于x的结点的序号(从1开始),若不存在这种结点,返回结果为0 时间复杂度 :O(n)int locate(LinkList list,int data){int index = 1;Node *c;c = list->next;while (c != NULL){if (c->data == data){return index;}index+=1;c = c->next;}return 0;}插⼊在表的第i个数据元素结点之前插⼊⼀个以x为值的新结点new获取第i的节点的直接前驱节点pre(若存在),使new.next = pre.next;pre.next = new;//在表head的第i个数据元素结点之前插⼊⼀个以x为值的新结点时间复杂度 :O(n)void insert(LinkList list, int position, int data) {Node *pre, *new;if (position == 1) {//若插⼊位置为1 则表⽰要插⼊到表的最前⾯即head的后⾯pre = list;} else {//pre表⽰⽬标位置的前⼀个元素所以-1pre = get(list, position - 1);if (pre == NULL) {printf("error:插⼊的位置超出范围");exit(0);}}new = malloc(sizeof(Node));new->data = data;new->next = pre->next;pre->next = new;list->length += 1;}删除删除给定位置的节点获取⽬标节点target的直接前驱节点pre(若pre与⽬标都有效),pre.next = target.next; free(target);//删除链表中第position个位置的节点时间复杂度 :O(n)void delete(LinkList list,int position){//获取要删除节点的直接前驱Node *pre;if (position == 1){ //如要删除的节点是第⼀个那直接前驱就是头结点pre = list;}else{pre = get(list,position-1);}////如果⽬标和前驱都存在则执⾏删除if (pre != NULL && pre->next != NULL){Node *target = pre->next; //要删除的⽬标节点//直接前驱的next指向⽬标的直接后继的nextpre->next = target->next;free(target);printf("info: %d被删除\n",target->data);list->length -= 1;}else{printf("error:删除的位置不正确!");exit(1);}}创建具备指定数据节点的链表//效率⽐较差算法时间复杂度 :O(n^2)LinkList createLinkList1(){LinkList list = initialLinkList();int a;//输⼊的数据int index = 1; //记录当前位置scanf("%d",&a);while (a != -1){ // O(n)insert(list,index++,a); // O(n^2) 每次都要从头遍历链表scanf("%d",&a);}return list;}//尾插算法记录尾节点从⽽避免遍历时间复杂度 :O(n)LinkList createLinkList2(){LinkList list = initialLinkList();int a;//输⼊的数据Node *tail = list;//当前的尾部节点scanf("%d",&a);while (a != -1){ // O(n)Node * newNode = malloc(sizeof(Node)); //新节点newNode->next = NULL;newNode->data = a;tail->next = newNode;//尾部节点的next指向新节点tail = newNode;//新节点作为尾部节点scanf("%d",&a);}return list;}//头插算法每次插到head的后⾯,不⽤遍历但是顺序与插⼊时相反时间复杂度 :O(n)LinkList createLinkList3(){LinkList list = initialLinkList();int a;//输⼊的数据Node * head = list;scanf("%d",&a);while (a != -1){ // O(n)Node * newNode = malloc(sizeof(Node)); //新节点newNode->next = NULL;newNode->data = a;newNode->next = head->next;//将原本head的next 交给新节点;head->next = newNode;//在把新节点作为head的next;scanf("%d",&a);}return list;}优缺点优点:在⾮终端节点插⼊删除时⽆需移动其他元素⽆需预分配空间,⼤⼩没有限制(内存够的情况)缺点:⽆法随机存取读取数据慢链表与顺序表的对⽐:操作顺序表链表读表元O(1)O(n)定位O(n)O(n)插⼊O(n)O(n)删除O(n)O(n)。

线性结构总结

线性结构总结

教学单元一:线性结构一、知识点总结知识点我的总结(可以对课堂相对应的知识点进行总结)(建议图文并茂,标识重难点)掌握程度自评(1-5分)5分表示掌握的非常最好线性表的顺序存储●线性表的顺序存储:线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。

●通常用数组来描述数据结构中的顺序存储结构重点:线性表的顺序存储示意图难点:结构体定义●顺序存储的优点与缺点:线性表的顺序存储结构,在存、读数据时,不管哪个位置,时间复杂都是O(1);而插入和删除时,时间复杂度都是O(n)优点:可以快速的存取任一位置的元素。

缺点:插入和删除元素时将移动大量元素。

5分线性表的链式存储●线性表的链式存储:线性表的链式存储:是用一组任意的存储单元存储线性表的数据元素,这组数据元素可以是连续的,也可以是不连续的。

●单链表与顺序表优缺点对比:(1)若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。

若需要频繁插入和删除时,宜采用单链表结构。

(2)当线性表中的元素个数变化较大或者根本不知道多大时,最好采用单链表结构,这样可以不用考虑存储空间大小问题。

而如果事先知道线性表的大致长度,例如一年2个月这种用顺序存储结构效率会高很多。

重点:线性表的链式存储示意图●结构体定义●链表的初始化1.首先为头节点开辟空间使用malloc(sizeof())结构;也可采用无头结点的链表2.采用头插法或者尾插法,此处示例尾插法难点:插入节点和删除节点插入:删除:5分●双向列表●循环链表顺序查找和折半查找●顺序查找的概念:顺序查找也称为线性查找,属于无序查找算法。

从数据结构线性表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于k的结点,表示查找失败。

重点:顺序查找的示意图(请点击播放)●顺序查找时间复杂度:查找成功时的平均查找长度为:(假设每个数据元素的概率相等)ASL=(1/n)∗(1+2+3+…+n)=(n+1)/2ASL=(1/n)∗(1+2+3+…+n)=(n+1)/2 ;当查找不成功时,需要n+1次比较,时间复杂度为O(n);所以,顺序查找的时间复杂度为O(n)●二分查找的概念:二分查找也称为是折半查找,属于有序查找算法。

线性结构的心得体会

线性结构的心得体会

线性结构的心得体会篇一:实验总结报告-栈和队列实验总结报告—栈和队列学号:姓名:时间:一、目的1.做实验的目的加深对线性结构栈和队列的理解,学会定义栈和队列的存储结构,加强对栈和队列操作机制的理解,掌握栈和队列的基本操作,了解栈和队列的一些应用。

2.撰写实验报告的目的对本次实验情况进行总结,加强对实验内容的理解,对实验过程有一个系统的认识,从中获得本次试验的经验,并对实验结果进行适当的分析,加深对栈和队列的理解和认识。

二、内容1.说明实验次数及实验内容本次实验用一次实验课时完成实验内容:(1)、编写函数CreatStack_sq , DestoryStack_sq , Push_sq , Pop_sq ,StackEmpty_sq 和StackTraverse_sq ,分别完成创建空栈,销毁栈,入栈,出栈,判断栈是否为空,遍历栈底到栈顶依次打印栈内元素等功能,完成后进行测试。

测试要求:在main 中,建立栈;判断栈是否为空;将0~9 入栈;将栈顶两个元素出栈,两元素求和后再入栈;从栈底到栈顶依次打印元素,再从栈顶到栈底打印元素;销毁栈。

void CreatStack_sq {...}void DestoryStack_sq{...}void Push_sq{...}bool Pop_sq{...}bool StackEmpty_sq{...}bool StackTraverse_sq{...}(2)、编写函数, CreateQueue_L , DestoryQueue_L , EnQueue_L ,DeQueue_L ,分别完成创建队列,销毁队列,入队列,出队列等操作,完成后进行测试。

测试要求:在主程序中,建立队列,将0~9 依次入队列,按入队列顺序出队列并打印,销毁队列。

void CreateQueue_L{}void DestoryQueue_L{}void EnQueue_L{}bool DeQueue_L{}(3)、回文是指正读反读均相同的字符序列,如”abba”和”abdba”均是回文,但”good”不是回文。

线性结构和非线性结构、稀疏数组、队列、链表(LinkedList)

线性结构和非线性结构、稀疏数组、队列、链表(LinkedList)

线性结构和⾮线性结构、稀疏数组、队列、链表(LinkedList)⼀、线性结构和⾮线性结构线性结构:1)线性绪构作为最常⽤的数据结构,其特点是数据元素之间存在⼀对⼀的线性关系2)线性结构有两种不同的存储结构,即顺序存储结构和链式存储结构。

顺序存储的线性表称为顺序表,顺序表中的存储元素是连续的3)链式存储的线性表称为链表,链表中的存储元素不⼀定是连续的,元素节点中存放数据元素以及相邻元素的地址信息4)线性结构常见的有:数组、队列、链表和栈,后⾯我们会详细讲解.⾮线性结构:⾮线性结构包括:⼆维数组,多维数组,⼴义表,树结构,图结构⼆、稀疏数组基本介绍:当⼀个数组中⼤部分元素为0,或者为同⼀个值的数组时,可以使⽤稀疏数组来保存该数组。

稀疏数组的处理⽅法是:1)记录数组⼀共有⼏⾏⼏列,有多少个不同的值2)把具有不同值的元素的⾏列及值记录在⼀个⼩规模的数组中,从⽽缩⼩程序的规模//实现原始数组和稀疏数组的相互转换;并存⼊⽂件进⾏保存和读取package com.zjl.sparsearray;import java.io.*;public class SparseArray {public static void main(String[] args) throws IOException {String file = "C:\\Users\\wenman\\Desktop\\test\\sapraseArr.txt";//定义⼀个原始的数组arr[11][11],并赋值arr[1][2] = 1, arr[2][3] = 2int[][] arr = new int[11][11];arr[1][2] = 1;arr[2][3] = 2;arr[3][4] = 2;//查看原始数据for (int[] arr_:arr) {for (int num:arr_) {System.out.printf("%d ",num);}System.out.println();}//获取原始数据中的数据个数int nums = 0;for (int[] arr_:arr) {for (int num:arr_) {if (num != 0){nums++;}}}//将原始数组转变为稀疏数组int[][] sparseArr = new int[nums + 1][3];sparseArr[0][0] = 11;sparseArr[0][1] = 11;sparseArr[0][2] = nums;int count = 0;for (int i = 0; i < 11; i++) {for (int j = 0; j < 11; j++) {if (arr[i][j] != 0){count++;sparseArr[count][0] = i;sparseArr[count][1] = j;sparseArr[count][2] = arr[i][j];}}}/*** 将稀疏数组存⼊到⽂件中*/FileWriter fileWriter = new FileWriter(file);for (int i = 0;i<sparseArr.length;i++) {fileWriter.write(sparseArr[i][0]+" "+sparseArr[i][1]+" "+sparseArr[i][2]+"\n");}fileWriter.close();//输出稀疏数组结构for (int[] arr_:sparseArr) {for (int num:arr_) {System.out.printf("%d ",num);}System.out.println();}/*** 从⽂件中读取数组*/BufferedReader bufferedReader = new BufferedReader(new FileReader(file));String line = null;int lineNum = 0;//初始化原始数组String[] s = bufferedReader.readLine().split(" ");int[][] arrs = new int[Integer.parseInt(s[0])][Integer.parseInt(s[1])];//获取原始数组中的值并赋值while ((line = bufferedReader.readLine())!=null) {String[] s1 = line.split(" ");arrs[Integer.parseInt(s1[0])][Integer.parseInt(s1[1])] = Integer.parseInt(s1[2]);}bufferedReader.close();//将稀疏数组变成原始数组// int[][] arrs = new int[sparseArr[0][0]][sparseArr[0][1]];// for (int i = 1 ; i < sparseArr.length; i ++) {// arrs[sparseArr[i][0]][sparseArr[i][1]] = sparseArr[i][2];// }for (int[] arr_:arrs) {for (int num:arr_) {System.out.printf("%d ",num);}System.out.println();}}}三、队列介绍:1、队列是⼀个有序列表,可以⽤数组或者链表来实现,2、遵循先⼊先出的原则。

线性结构知识点总结

线性结构知识点总结

线性结构知识点总结一、线性结构的定义线性结构是数据元素之间存在一对一的线性关系。

数据元素是有序排列的,在数据元素之间存在唯一的前驱和后继关系。

线性结构是最基本、最常用的一种数据结构,具有清晰的先后次序关系。

二、线性结构的特点1. 有序性:线性结构中的元素是有序排列的,每个元素都有唯一的前驱和后继。

2. 直接关系:除了首尾两个元素外,任意两个相邻的元素都有直接关系。

三、线性结构的常见类型线性结构的常见类型包括线性表、栈、队列、串、数组、链表等。

下面分别介绍这些线性结构的特点和实现方式。

1. 线性表线性表是线性结构的一种基本形式,它是具有相同特性的数据元素的有限序列。

线性表的特点是元素之间有直接关系,元素的个数是有限的。

线性表常用的实现方式包括顺序表和链表。

1.1 顺序表顺序表是指用一维数组实现的线性表。

它的特点是元素的逻辑顺序和物理顺序相同,元素之间通过数组下标来进行访问。

顺序表的优点是支持随机访问和元素的快速插入和删除,缺点是需要提前确定表的大小,插入和删除操作可能需要移动大量元素。

1.2 链表链表是另一种常见的线性表实现方式。

它的特点是通过指针将元素连接在一起,元素的逻辑顺序和物理顺序可以不同。

链表的优点是可以动态分配内存空间,插入和删除操作效率高,缺点是无法随机访问,需要额外的指针空间。

2. 栈栈是一种特殊的线性表,它只允许在一端进行插入和删除操作。

栈的特点是先进后出,后进先出,类似于弹夹。

栈的常见实现方式包括顺序栈和链式栈,其应用包括函数调用、表达式求值、括号匹配等。

3. 队列队列也是一种特殊的线性表,它只允许在一端进行插入操作,在另一端进行删除操作。

队列的特点是先进先出,后进后出,类似于排队。

队列的常见实现方式包括顺序队列和链式队列,其应用包括任务调度、缓冲区管理等。

4. 串串是由零个或多个字符组成的有限序列,它是线性结构的一种特殊形式。

串的特点是每个字符之间存在唯一的前驱和后继关系,同时支持字符的插入、删除和替换等操作。

数据结构之线性结构

数据结构之线性结构

链表的 代码实现
//删除编号为x的结点 void del(int x) { int p,q; if(head==x) head=list[x].left; p=list[x].left; q=list[x].right; list[p].right=list[x].right; list[q].left=list[x].left; list[x].left=0; list[x].right=0; }
//把编号x的元素插到p号点之后 void insert(int p,int x) { list[x].right=list[p].right; list[x].left=p; list[list[p].right].left=x; list[p].right=x; }
//查找链表中的名为helang的结点的编号 void searchList(string s) { int p; p=head; while((p!=0) && (list[p].name!="helang"))p=list[p].right; if(list[p].name=="helang") cout<<p; else cout<<"not found"; }
队首(head)
队列
队尾(tail)
队列(queue)是另一种特殊的线性表,它的特点是删除操作 在一头进行,插入操作在另一头进行。 允许删除的一端称为队首(head),允许插入的一端称为队尾 (tail)。 不含任何元素的队称为空队。 队列的修改是按先进先出(First In First Out)的原则进行
链表(list),由多个结点连接而成的链状结构。每个结 点包含两部分,数值和存放结点间的相互关系。

数据结构期末总结高中

数据结构期末总结高中

数据结构期末总结高中导言:数据结构是计算机科学中的一门重要基础课程,主要介绍了数据的存储、组织和管理方式,以及不同数据存储结构之间的优缺点及操作方法。

在高中阶段,学习数据结构可以帮助我们更好地理解计算机内部的数据处理过程,扩展我们的计算能力,并为日后的学习和工作打下良好的基础。

本篇文章将从以下几个方面总结数据结构课程的内容和学习体会:一、线性结构二、树形结构三、图形结构四、常见的算法五、总结一、线性结构:在线性结构的学习中涉及到了线性表、栈、队列、链表等概念和操作。

1.线性表:线性表是一种最常用且常见的数据结构,它的特点是数据元素之间存在一对一的线性关系。

学习了线性表的基本操作和简单变形后,我对数据的存储和访问方式有了更深刻的理解。

2.栈:栈是一种先进后出(Last In First Out)的数据结构,类似于平时使用的弹夹。

了解了栈的基本特点以及它的应用场景,我可以更好地理解递归的本质和编写递归算法。

3.队列:队列是一种先进先出(First In First Out)的数据结构,类似于平时排队等候。

通过学习队列的基本实现方式和应用场景,我可以更好地理解CPU的调度算法和任务排队等待的原理。

4.链表:链表是一种非连续存储结构,通过指针将一组零散的内存块串联起来。

学习了单链表、双链表和循环链表等结构的实现方式和操作,我对动态内存管理和链表算法的设计有了更深入的认识。

二、树形结构:树形结构是一种多对一的数据结构,它的特点是具有层次关系。

1.二叉树:二叉树是一种数据集合,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。

学习了二叉树的基本定义和遍历方式后,我能够更好地理解搜索算法和排序算法的实现原理。

2.平衡二叉树:平衡二叉树是一种特殊的二叉树,它的左右子树的高度差不超过1。

了解了平衡二叉树的实现方法和旋转操作,我可以更好地理解红黑树等平衡二叉树的应用场景。

3.哈夫曼树:哈夫曼树是一种带权路径最短的树形结构,主要用于数据压缩和编码。

数据结构学习(C++)——线性链式结构总结

数据结构学习(C++)——线性链式结构总结

数据结构学习(C++)——线性链式结构总结在开始写这些文章之前,我曾经有个想法,能不能以单链表为基础,完成所有的线性链式结构?实践证明,是可以的,就像你看到的这样。

我做这个尝试的起因是,看不惯现在教科书凌乱的结构:罗列了一大堆ADT或者是templat class,好像这些都要你去记似的。

殊不知,只有提取共性,突出个性,才能更明显的表现出各种数据结构的差异,显示数据结构的进化发展的过程,看出变化的内在需求。

借用《C++沉思录》作者的一句话,“避免重复”。

在以后的应用中,你可能需要单独的写出一个class——打个比方,为了实现栈,你没有必要先写一个线性表,然后再继承得到栈;但假如你已经有了一个线性表了,你还需要另起炉灶再重写一个栈吗?对于一本书来说,本来就是假定读者在看后面的章节的时候,已经对前面的章节有所了解;即使象《C++沉思录》这样的从以前发表在杂志上的文章整理出的书,也能看到循序渐进的影子。

如果在后面的章节又把前面的东西重复一遍,我只能认为他是在骗稿费。

我把以前的代码总结一下,列表如下(因为我画不好图):单链表(List<Type>)多项式节点表达式节点修改部分操作添加向前指针域限制操作多项式表达式循环链表双向链表栈和队列我们从单链表出发,通过对应的变化,得到了绿色的一行。

突然之间我觉得自己很可悲,看了100多页书,最后得到竟然只是这么一个表。

不管怎么说,这也是我看了这么多页书的结晶,让我们看看能从这表里得到什么。

首先,单链表是一个容器,他是为了存取数据而存在的。

如果里面存的是多项式的节点,那么他就是一个多项式;如果里面存的是表达式节点,那么他就是一个表达式。

这让我想起了以前曾经困扰我的语义问题:多项式究竟是一个存了多项式节点的单链表呢,还是包含了一个存了多项式节点的单链表?现在我的想法是,这并不重要,怎么理解都行。

其次,循环链表、双向链表、栈和队列也是容器,只是具体的操作实现或者对外的行为和单链表有所差别。

线性数据结构

线性数据结构

线性数据结构线性数据结构就是:顺序表和链表。

其他的就是⾮线性数据结构,⽐如树,图等。

线性数据结构的特点是,⼀对⼀,⼀个数据只有⼀个后继和⼀个前驱;⽽⾮线性数据结构则是⼀对多。

1、顺序表顺序表是个逻辑概念,顺序表的相邻元素在物理位置上也是相邻的。

通常我们采⽤数组实现顺序表,我们可能会把这两者混为⼀谈。

数组是基于顺序表逻辑实现的,但在细微之处有些许差别,⽐如数组下标从0开始,顺序表下标从1开始。

顺序表的特点是随机存取⽅便,不可扩充。

2、链表当我们需要存放⼤量动态的数据时,这时就需要链表登场了。

链表不需要数据存在连续的位置,它的存储结构是每个数据都有下⼀个结点的地址,所有的数据串成⼀条链,从第⼀个数据开始问,我们可以找到任何⼀个数据。

相对于顺序表直接给出了每个数据的位置编号,链表的查找⽐较费事。

链表可以有⼀个空的头节点dummy,不存放数据,只⽤来做标识。

⽅便数据的增删,并且对于空表⽅便处理。

除了上⾯的单向链表,链表还有双向链表,循环链表,⼗字链表等变式。

单链表反转链表反转⼀般有三种⽅法,原地反转,头插法反转,递归反转。

其中递归反转最简单简洁,但是空间复杂度更⾼。

下⾯分别介绍。

1.原地反转⾸先让pre的next指向cur的next;再让cur的next指向头节点的下⼀个结点;这时已经反转了结点,此时链表第⼀个结点变成了当前反转的结点;再让头节点的next指向cur;最后移动cur到下⼀个要反转的结点。

重复上述步骤,直到cur为null。

此时头节点也指向最后⼀个节点了。

带头节点的链表:static LinkNode reverse1(LinkNode l){if(l.next == null || l.next.next == null){return l;}LinkNode pre = l.next; // pre 不动, 移动头节点LinkNode cur = pre.next;while(cur != null){pre.next = cur.next;cur.next = l.next;l.next = cur;cur = pre.next;}return l;}不带头结点的链表:⼀样的做法⼀个指向pre,⼀个指向cur。

基本数据结构-线性结构

基本数据结构-线性结构

西安电子科技大学 - Xidian University
move a onto b

先将a和b上的其他木块移回到它们的初始位置,然 后将木块a摞在木块b上.
2
Example: move 3 onto 6
4 7 0 1 3 5 6 8 9 0 1 2 3 4 5 6 7 8 9
3 0 1 2 3 4 5 6 7 8 9
head

a1 头结点
带头结点的单向链表

ai-1 ai ai+1 an-1
a2
∧ an
西安电子科技大学 - Xidian University
单链表中插入元素

将元素ai所在结点的地址赋给元素e结点的指针域: S->next = P->next;

修改元素ai-1所在结点指针域的值: P->next = S;
∧ a1
a2

ai

an-1
an ∧
(a) 双向链表
a1
a2

an-1
an
tail
(b) 循环单链表
西安电子科技大学 - Xidian University
单链表的插入和删除

链式存储:任意存储单元存储元素 链表结点包括数据域和指针域 插入或删除一个元素,只需修改结点指针域 访问任一元素必须从链表头指针开始
a1 a2
d
例如:由n个元素构成的一维数组a 由下标i确定数组元素a[i],其位置关 系为(在C/C++/Java中,下标从0开始): Loc(a[i])=Loc(a[1])+(i-1)*d (1≤i≤n)
ai+1

数据结构之线性结构

数据结构之线性结构

数据结构之线性结构数据结构之线性结构(一):概念与基本操作线性结构是数据结构的一种,它是一种最简单的结构。

线性结构的特点是数据元素之间存在一对一的关系,即除了第一个和最后一个元素外,其他元素都有前驱和后继。

线性结构的代表类型有线性表、队列、栈等。

1.1 线性表线性表是线性结构中最基本的一种,它是由零个或多个数据元素组成的有限序列。

线性表的数据元素具有相同的数据类型。

线性表的主要操作有:•初始化:创建一个空的线性表。

•插入:在线性表的指定位置插入一个数据元素。

•删除:删除线性表的指定位置的数据元素。

•查找:查找线性表中指定数据元素的位置。

•修改:修改线性表中指定位置的数据元素。

•输出:输出线性表中的所有数据元素。

1.2 栈栈是线性结构的一种,它是一种后进先出(Last In First Out, LIFO)的数据结构。

栈的主要操作有:•初始化:创建一个空的栈。

•压入:将一个数据元素放入栈顶。

•弹出:移除栈顶的数据元素。

•查找:查找栈中指定数据元素的位置。

•输出:输出栈中的所有数据元素。

数据结构之线性结构(二):常见线性结构及其应用线性结构在计算机科学中有广泛的应用,下面介绍几种常见的线性结构及其应用。

2.1 线性表的应用线性表在计算机科学中有广泛的应用,例如数组、链表等。

数组是一种常见的线性表,它是一组相同类型的数据元素的集合。

数组的特点是可以通过索引直接访问元素,但数组的容量固定,不能动态扩展。

链表是一种动态的线性表,它由一系列节点组成,每个节点包含数据元素和指向下一个节点的指针。

链表的优点是容量可以动态扩展,但访问节点的时间复杂度较高。

2.2 栈的应用栈在计算机科学中有广泛的应用,例如函数调用栈、表达式求值等。

函数调用栈是一种用于存储函数调用的栈,它用于管理函数的执行顺序和局部变量的存储。

表达式求值是一种使用栈来计算表达式值的方法,例如算术表达式、逻辑表达式等。

栈的特点是后进先出,可以方便地处理表达式中的括号匹配和运算顺序。

数据结构知识点总结,有工大老师多经验编写(1)

数据结构知识点总结,有工大老师多经验编写(1)

数据结构知识点总结,有工大老师多经验编写(1)数据结构是计算机领域中非常重要的一门课程,无论是在学术研究还是实践运用上都有广泛的应用。

在学习数据结构的过程中,必须掌握一些基本的知识点和重点难点,下面是对这些知识点的总结。

一、线性结构线性结构是指数据元素之间存在线性关系的一种结构,包括数组、链表、栈和队列等。

这些数据结构都有各自的特点和应用范围,比如数组适合于查找,链表适合于插入和删除。

其中,栈和队列是比较常用的数据结构,栈具有“先进后出”(Last In First Out,LIFO)的特点,而队列具有“先进先出”(First In First Out,FIFO)的特点。

二、树结构树是一种非线性结构,适用于组织具有层次结构的数据。

其中,二叉树是最基本的树结构之一,它的每个节点最多只有两个子节点。

二叉树又可以分为满二叉树、完全二叉树和平衡二叉树等。

除了二叉树,还有多叉树、红黑树、B树、B+树等树结构。

三、图结构图是一种更加复杂的非线性结构,它由节点和边组成,节点之间可以存在多个边。

图可以分为有向图和无向图,常见的算法有深度优先搜索(DFS)和广度优先搜索(BFS)。

四、排序算法排序算法是数据结构中的重要内容,它可以将无序的数据按照某种规则排列成有序的数据。

常见的排序算法包括冒泡排序、插入排序、选择排序、快速排序、归并排序等。

不同的排序算法在时间复杂度和空间复杂度等方面存在差异,需要根据实际情况选择合适的算法。

五、查找算法查找算法是指在一堆数据中查找特定数据的过程。

常见的查找算法有顺序查找、折半查找、哈希查找等。

在实际应用中,需要根据数据量和查找方式选择合适的算法。

六、综合实践学习数据结构不仅需要掌握理论知识,还需要进行实践操作。

在实践中可以加深对数据结构的理解,提高编程技能。

可以通过刷题、写代码等方式进行实践操作。

综上所述,以上是数据结构的基本知识点总结。

对于学生来说,只有掌握了这些知识点,才能更好地理解和应用数据结构。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

template<class T> void Swap(T&a ,T&b) { T temp; temp=a; a=b; b=temp; }
函数原型: template<class T> void Cocktail_sort (T list[],int list_length);
请每位同学写在纸上交上来 (请写上班学号和姓名)。
参考解答
(1)删除单链表中所有大于min且小于max的元素。 (2)first->7->0->9->2->8。
算法阅读
list是一个顺 序存储的线 性表的非递 减序列,阅 读算法,说 明其功能。 struct SListTable { int *elem; int size; }; void fun(SListTable& list) { int i=1; int j=0; while(i<list.size) { if(list.elem[i]!=list.elem[j]) { j++; list.elem[j]=list.elem[i]; } i++; } size=j; }
Chapter3 线性表(数据描述)
1、线性结构的特点 2、线性表的公式化描述:顺序表
– 插入、删除、查找等基本操作算法
– 如何实现内存的有效使用?动态分配一维数组!
3、线性表的链式描述(链表)
– 插入、删除、查找等基本操作算法
– 头、尾指针的使用,对算法的影响!
线性表(续)
4、循环链表的遍历、双向链表的定义及相关操作
B
4、在双向链表存储结构中,删除p所指的结点时须修改指针 ( )。 A A. p->llink->rlink=p->rlink; p->rlink->llink=p->llink; B. p->llink=p->llink->llink; p->llink->rlink=p; C. p->rlink->llink=p; p->rlink=p->rlink->rlink
数据结构与算法
授课教师:张剑波 方 芳 授课班级:111081-4班 115081-2班
2009年秋季
阶段小结(一)线性结构
教学内容
相关章节重要知识点回顾 课堂练习 第一阶段作业及实习小结
相关章节
Chapter2 程序性能 Chapter3 数据描述(线性表) Chapter4 数组和矩阵 Chapter5 堆栈 Chapter6 队列 Chapter7 散列 补充数据结构:字符串
D. p->rlink=p->llink->llink; p->llink=p->rlink->rlink;
5、递归过程或函数调用时,处理参数及返回地址,要用一 种称为( )的数据结构。 C
A.队列
B.多维数组
C.栈
D. 线性表
6、用I表示入栈操作,O表示出栈操作,若元素入栈顺序为 1234,为了得到1342出栈顺序,相应的I和O操作串为( )。 A.IIOOIIOO C.IOIIOIOO B.IOIOIIOO D.IOIIOOIO
2、计算机执行下面的语句时,语句s的执行次数为 for(i=1;i<n-1;i++) for(j=1;j<=i;j++) s;

(n 1)( n 2) 1 i 2 i 1 j 1 i 1
n2 i n2
3、下面关于线性表的叙述中,错误的是哪一个?( ) A.线性表采用顺序存储,必须占用一片连续的存储单元。 B.线性表采用顺序存储,便于进行插入和删除操作。 C.线性表采用链接存储,不必占用一片连续的存储单元。 D.线性表采用链接存储,便于插入和删除操作。
B
2、解答题
a11 a 21 A a12 a22 a32 a23 a33 a34 ... an 1, n 2 an 1, n 1 an , n 1 an 1, n an, n
1、设有三对角矩阵,如上图所示,将带状区域中的元素 ai,j(|i-j|≤1)放在一维数组B中,则 (1)B的大小为多少? (2)元素ai,j在B中的位置是什么?(B的下标从0开始计, 以行优先方式存储)
堆栈(续)
3、链式栈
– 自定义链式栈的实现:LinkedStack
– 插入与删除仅在栈顶(链头)处执行 – 适合于多栈操作 4、栈的应用 – 表达式计算 – 递归:汉诺塔
– 火车车厢重排算法
Chapter6 队列
1、队列的结构特点:FIFO
2、队列的顺序存储表示——循环队列(重点) – 顺序队列的”假溢出“问题 – 循环队列队空、队满的条件 – 循环队列的插入、删除操作 – 循环队列的实现:Queue
4、矩阵类 – Matrix – 矩阵的基本运算:加、减、乘法
数组和矩阵(续)
5、特殊矩阵的压缩 – 对角矩阵 – 三对角矩阵 – 三角矩阵、对称矩阵 6、稀疏矩阵 – 两种描述形式:三元组表、十字链表 – 掌握:SparseMatrix快速转置算法
Chapter5 栈
1、栈的结构特点:LIFO 2、顺序栈 – 自定义Stack的实现 – 栈空、栈满条件 – 插入、删除操作(压栈、弹栈) – 了解:如何实现多个栈共享存储空间
Chapter2 程序性能
1、简单搜索(查找)算法 – 顺序查找 – 折半查找:针对有序线性表(如数组) 2、简单排序算法:熟练掌握 – 选择排序 – 冒泡排序 – 插入排序
程序性能(续)
3、程序空间复杂度 – 组成及计算 4、程序时间复杂性分析 – 掌握“操作计数”法估算 5、渐近符号O、Ω、Θ – 使用上述符号准确描述算法的时间复杂度 – 以三种简单排序算法为例
9、算术表达式a+b*(c+d/e)转为后缀表达式后为( )。 A.ab+cde/* C.abcde/*++ B.abcde/+*+ D.abcde*/++
B
10、设有一组关键码{19,01,23,14,55,20,84,27, 68,11,10,77},采用散列函数H(key)=key%13,处理 冲突的方法是线性探测再散列的方法(即dj+1=(dj+1)%m) 若在0~18(即m=19)的散列地址空间中对该关键码构造散 列表,则关键码14对应的地址是( )。 A.1 B.2 C.3 D.14
队列(续)
3、队列的链式存储表示——链式队列 –插入与删除分别在队尾和队头处执行 – 循环队列的实现:LinkedQueue 4、队列的应用
– 再解:火车车厢重排 – 循环队列的应用:键盘输入缓冲区等
Chapter7 散列
1、字典的线性表描述:有序链表SortedChain
2、散列表
– 散列函数的构造方法:除留取余法
鸡尾酒排序示例
3 3
1
5 1
3
1 4
2
4 5
4
9 6
5
6 7
6
7 2
7
2 9
9
1
2
3
4
5
6
7
9
参考解答
template<class T> void cocktail_sort(T list[], int list_length) { // the first element of list has index 0 int bottom = 0; int top = list_length - 1; bool swapped = true; while(swapped == true) // if no elements have been swapped, then the list is sorted { swapped = false; for(int i = bottom; i < top; i++) { if(list[i] > list[i + 1]) // test whether the two elements are in the correct order { Swap(list[i], list[i + 1]); // let the two elements change places swapped = true; } } // decreases top the because the element with the largest value in the unsorted // part of the list is now on the position top top = top - 1;
7 7
72 68 23 49 8 9 10 11 12 13
3、算法阅读
1、已知一带表头节点的单链表L为(5,7,0,9,4,2,8), first指针指向表头节点,data为链表的值域,link为指针域。阅 读以下程序,回答问题。 template <class Type> void Chain<Type>::fun(Type min, Type max) { ChainNode<Type> *pr=first, *p=first->link; while(p) { if( p->data>min && p->data<max) { pr->link=p->link; delete p; p=pr->link; } else { pr=p; p=pr->link; } (1)说明该程序的功能; (2)试画出执行L.fun(3,7);调用 } 后的L链表的逻辑示意图。 }
相关文档
最新文档