大家好,欢迎来到IT知识分享网。
线性表的顺序存储实验
循环链表实验
串的实现实验
数组实验
二叉树实验
查找
排序实验
数据结构的基本概念和术语
了解数据结构的基本概念,理解常用术语
基本概念:数据与数据元素
数据元素间的四种结构关系。
学号
|
姓名
|
语文
|
数学
|
C语言
|
|
张三
|
85
|
54
|
92
|
|
李四
|
92
|
84
|
64
|
|
王五
|
87
|
74
|
73
|
|
|
|
|
|
…
|
|
|
|
|
|
特征
|
示例
|
集合
|
元素间为松散的关系
|
|
线性结构
|
元素间为严格的一对一关系
|
如上面的成绩表中各元素
|
树形结构
|
元素间为严格的一对多关系
|
|
图状结构(或网状结构)
|
元素间为多对多关系
|
|
逻辑结构
|
|
“数据结构”定义中的“关系”指数据间的逻辑关系,故也称数据结构为逻辑结构。
|
存储结构
|
|
数据结构在计算机中的表示称为物理结构。又称存储结构。
|
顺序存储结构
|
||
链式存储结构
|
位
,8位为一字节,两个字节为一字,字节、字或更多的二进制位可称为
位串。
在逻辑描述中,把位串称为元素或
结点
。
数据域
(Data Field)。
int stuno;/*数据项,也称stu位串中的一个子位串,或叫做数据域*/
char name[20];
int maths;
int language;
int c_language;
} classonestu[50];
|
特征
|
例
|
原子类型
|
值在逻辑上不可分解
|
int float
|
结构类型
|
值由若干成分按某种结构组成
|
struct stu
|
处理方法(算法)
与处理结果->数据类型
抽象数据类型的表示与实现
了解抽象数据类型的定义、表示和实现方法
抽象数据类型表示法、类C语言语法
抽象数据类型表示法
抽象数据类型分类
|
|
原子类型
|
值不可分解,如int
|
固定聚合类型
|
值由确定数目的成分按某种结构组成,如复数
|
可变聚合类型
|
值的成分数目不确定如学生基本情况
|
名称
|
线性表
|
|
数据对象
|
D={a
i | a i (-ElemSet,i=1,2,…,n,n>=0} |
任意数据元素的集合
|
数据关系
|
R1={<a
i-1 ,a i >| a i-1 ,a i (- D,i=2,…,n} |
除第一个和最后一个外,每个元素有唯一的直接前趋和唯一的直接后继
|
基本操作
|
ListInsert(&L,i,e)
|
L为线性表,i为位置,e为数据元素。
|
ListDelete(&L,i,e)
|
||
…
|
类C语言语法示例
|
|
|
|||
1、预定义常量和类型
|
#define TRUE 1
#define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 typedef in Status; //Status是函数的类型,其值是函数结果状态代码。 |
|
|||
2、数据结构的存储结构
|
typedef ElemType first;
|
|
|||
3、基本操作的算法
|
函数类型 函数名(函数参数表){
//算法说明 语句序列 }//函数名 |
|
|||
4、赋值语句
|
简单赋值:
|
变量名=表达式;
|
|
||
串联赋值:
|
变量名1=变量名2=…=变量名k=表达式;
|
|
|||
成组赋值:
|
(变量名1,…,变量名k)=(表达式1,…,表达式k);
结构名=结构名; 结构名=(值1,…,值k); 变量名[]=表达式; 变量名[起始下标..终止下标]=变量名[起始下标..终止下标]; |
||||
交换赋值:
|
变量名<–>变量名;
|
|
|
||
条件赋值:
|
变量名=条件表达式?表达式?表达式T:表达式F
|
|
|
||
5、选择语句
|
1、if(表达式) 语句;
2、if(表达式) 语句; else 语句; 3、switch(表达式){ case 值1:语句序列1;break;
…
case 值n:语句序列n;break; default:语句序列n+1;break; } 4、switch{ case 条件1:语句序列1;break;
…
case 条件n:语句序列n;break; default:语句序列n+1;break; } |
|
|
||
6、循环语句
|
for(赋初值表达式;条件;修改表达式序列)语句;
while(条件)语句; do{ 语句序列}while(条件); |
|
|
||
7、结束语句
|
return [表达式];
return; //函数结束语句 break; //case结束语句 exit(异常代码); //异常结束语句 |
|
|
||
8、输入和输出语句
|
scanf([格式串],变量1,…,变量n);
|
|
|
||
9、注释
|
//文字序列
|
|
|
||
10、基本函数
|
max(表达式1,…,表达式n)
min,abs,floor,ceil,eof,eoln |
|
|
||
11、逻辑运算
|
&&与运算;||或运算
|
|
|
ADT List{
i
| a
i
(-ElemSet,i=1,2,…,n,n>=0}
i-1
,a
i
>| a
i-1
,a
i
(- D,i=2,…,n}
DestroyList(&L)
ListInsert(&L,i,e)
ListDelete(&L,i,&e)
#define ERROR 0 #define OK 1 struct STU { char name[20]; char stuno[10]; int age; int score; }stu[50]; struct LIST { struct STU stu[50]; int length; }L; int printlist(struct LIST L) int listinsert(struct LIST *L,int i,struct STU e) main() strcpy(e.name,”bobjin”); strcpy(e.stuno,””); e.age=80; e.score=1000; listinsert(&L,1,e); printlist(L); printf(“List length now is %d./n/n”,L.length); } |
E:/ZM/Zmdoc/datastru/class02>listdemo name stuno age score zmofun 80 1000 List length now is 1. name stuno age score bobjin 80 1000 zmofun 80 1000 List length now is 2. |
算法及算法设计要求
掌握算法的定义及特性,算法设计的要求
算法的特性,算法设计要求
算法设计的要求
for(i=0;i<4;i++)
}/*上面是一个类似华容道游戏中判断游戏是否结束的算法*/
有穷性
|
一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都可在有穷时间内完成;
|
确定性
|
算法中每一条指令必须有确切的含义,读者理解时不会产生二义性。有任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。
|
可行性
|
一个算法是能行的,即算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的。
|
输入
|
一个算法有零个或多个的输入,这些输入取自于某个特定的对象的集合。
|
输出
|
一个算法有一个或多个的输出。这些输出是同输入有着某些特定关系的量。
|
有穷性
|
haha()
{/*only a joke,do nothing.*/ } main() {printf(“请稍等…您将知道世界的未日…”); while(1) haha(); } |
确定性
|
float average(int *a,int num)
{int i;long sum=0; for(i=0;i<num;i++) sum+=*(a++); return sum/num; } main() {int score[10]={1,2,3,4,5,6,7,8,9,0}; printf(“%f”,average(score,10); } |
可行性
|
|
输入
|
|
输出
|
getsum(int num)
{ int i,sum=0; for(i=1;i<=num;i++) sum+=i; } /*无输出的算法没有任何意义, |
算法正确性的四个层次
|
|
程序不含语法错误。
|
max(int a,int b,int c)
{ if (a>b) {if( a>c ) return c ; else return a ; } } |
程序对于几组输入数据能够得出满足规格说明要求的结果。
|
max(int a,int b,int c)
{ if (a>b) {if(a>c) return a; else return c; } } /* 8,6,7 */ /* 9,3,2 */ |
程序对于精心选择的典型、苛刻而带有刁难性的几组输入数据能够得出满足规格说明要求的结果。
|
max(int a,int b,int c)
{ if (a>b) {if(a>c) return a; else return c; } else {if(b>c) return b; else return c; } } |
程序对于一切合法的输入数据都能产生满足规格说明要求的结果。
|
|
|
算法一
|
算法二
|
在三个整数中求最大者
|
max(int a,int b,int c)
{if (a>b) {if(a>c) return a; else return c; } else {if(b>c) return b; else return c; }/*无需额外存储空间,只需两次比较*/ |
max(int a[3]) {int c,int i; c=a[0]; for(i=1;i<3;i++) if (a[i]>c) c=a[i]; return c; } /*需要两个额外的存储空间,两次比较,至少一次赋值*/
/*共需5个整型数空间*/ |
求100个整数中最大者 | 同上的算法难写,难读 | max(int a[ 100 ]) {int c,int i; c=a[0]; for(i=1;i< 100 ;i++) if (a[i]>c) c=a[i]; return c; } /*共需102个整型数空间*/ |
算法效率的度量和存储空间需求
掌握算法的渐近时间复杂度和空间复杂度的意义与作用
渐近时间复杂度的意义与作用及计算方法
渐近时间复杂度的意义
程序在计算机上运行所需时间的影响因素 | |
算法本身选用的策略 | |
问题的规模 | 规模越大,消耗时间越多 |
书写程序的语言 | 语言越高级,消耗时间越多 |
编译产生的机器代码质量 | |
机器执行指令的速度 |
原操作
,以该基本操作重复执行的次数作为算法的时间量度。(原操作在所有该问题的算法中都相同)
(n)=
O
(f(
n
))
渐近时间复杂度
,简称
时间复杂度
。
求4*4矩阵元素和,T(4)=O(f(4)) f=n*n; | sum(int num[4][4]) { int i,j,r=0; for(i=0;i<4;i++) for(j=0;j<4;j++) r+=num[i][j]; /* 原操作 */ return r; } |
最好情况: T(4)=O(0) 最坏情况: T(4)=O(n*n) | ispass(int num[4][4]) { int i,j; for(i=0;i<4;i++) for(j=0;j<4;j++) if(num[i][j]!=i*4+j+1) return 0; return 1; } |
频度
相同。语句的
频度
指的是该语句重复执行的次数。
语句 | 频度 | 时间复杂度 |
{++x;s=0;} | 1 | O(1) |
for(i=1;i<=n;++i) {++x;s+=x;} | n | O(n) |
for(j=1;j<=n;++j) for(k=1;k<=n;++k) {++x;s+=x;} | n*n | O(n*n) |
O(log n) | ||
基本操作的执行次数不确定时的时间复杂度 | |
平均时间复杂度 | 依基本操作执行次数概率计算平均 |
最坏情况下时间复杂度 | 在最坏情况下基本操作执行次数 |
(n)=
O
(f
(n)
)
线性表的类型定义
掌握线性表的概念和类型定义
线性表的类型定义
线性表的类型定义
在数据元素的非空有限集中, (1)存在唯一的一个被称做“第一个”的数据元素; (2)存在唯一的一个被称做“最后一个”的数据元素; (3)除第一个之外,集合中的每个数据元素均只有一个前驱; (4)除最后一个之外,集合中每个数据元素均只有一个后继。 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
学号 | 姓名 | 语文 | 数学 | C语言 |
张三 | 85 | 54 | 92 | |
李四 | 92 | 84 | 64 | |
王五 | 87 | 74 | 73 | |
… |
数据项
组成(如上例3)。这时常把数据元素称为
记录
。含有大量记录的线性表又称
文件
。
a 1 | … | a i-1 | a i | a i+1 | … | a n |
i
是
a
i+1
的
直接前驱
元素,
a
i+1
是
a
i
的
直接后继
元素。
a
i
是第i个元素,把i称为数据元素
a
i
在线性中的
位序
。
i
| a
i
(-ElemSet,i=1,2,…,n,n>=0}
i-1
,a
i
>| a
i-1
,a
i
(- D,i=2,…,n}
DestroyList(&L)
ClearList(&L)
ListEmpty(L)
ListLength(L)
GetElem(L,i,&e)
LocateElem(L,e,compare())
PriorElem(L,cur_e,&pre_e)
NextElem(L,cur_e,&next_e)
ListInsert(&L,i,e)
ListDelete(&L,i,&e)
ListTraverse(L,visit())
union(List &La,List &Lb)
//InitList
//GetElem
//ListInsert
//union
//MergeList
——————-List Demo is running…—————- First is InsertList function. name stuno age score stu1 80 1000 stu2 80 1000 List A length now is 2. name stuno age score stu1 80 1000 stu2 80 1000 stu3 80 1000 List A length now is 3. name stuno age score zmofun 80 1000 bobjin 80 1000 stu1 80 1000 List B length now is 3. Second is UnionList function. Now union List A and List B….. name stuno age score stu1 80 1000 stu2 80 1000 stu3 80 1000 zmofun 80 1000 bobjin 80 1000 List A length now is 5. Welcome to visit http://zmofun.heha.net ! |
线性表的顺序表示和实现
掌握线性表的顺序表示和实现方法
线性表的顺序表示和实现方法
线性表的顺序存储的实现方法
逻辑结构 | “数据结构”定义中的“关系”指数据间的逻辑关系,故也称数据结构为逻辑结构。 | |
存储结构 | 数据结构在计算机中的表示称为物理结构。又称存储结构。 | |
顺序存储结构 | ||
链式存储结构 |
|
| a[9] |
|
a
i+1
)=LOC(
a
i
)+l
a
i
)=LOC(
a
1
)+(i-1)*l
a
1
)是线性表的第一个数据元素的存储位置,通常称做线性表的
起始位置
或
基地址
。常用b表示。
顺序存储结构
或顺序映象。
顺序表
。顺序表的特点是以元素在计算机内物理位置相邻来表示线性表中数据元素之间的逻辑关系。
线性表的动态分配顺序存储结构 |
#define LIST_INIT_SIZE 100 #define LISTINCREMENT 10 typedef struct{ ElemType *elem; //存储空间基址 int length; //当前长度 int listsize; //当前分配的存储容量以一数据元素存储长度为单位 }SqList; |
序号 | 数据元素 | 序号 | 数据元素 | 序号 | 数据元素 | 序号 | 数据元素 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
| <- 25 |
|
|
|
| -> 24 |
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
插入前n=8;插入后n=9; | 删除前n=8;删除后n=7; |
顺序表的插入算法 |
status ListInsert(List *L,int i,ElemType e) { struct STU *p,*q; if (i<1||i>L->length+1) return ERROR; q=&(L->elem[i-1]); for(p=&L->elem[L->length-1];p>=q;–p) *(p+1)=*p; *q=e; ++L->length; return OK; }/*ListInsert Before i */ |
顺序表的合并算法 |
void MergeList(List *La,List *Lb,List *Lc) { ElemType *pa,*pb,*pc,*pa_last,*pb_last; pa=La->elem;pb=Lb->elem; Lc->listsize = Lc->length = La->length + Lb->length; pc = Lc->elem = (ElemType *)malloc(Lc->listsize * sizeof(ElemType)); if(!Lc->elem) exit(OVERFLOW); pa_last = La->elem + La->length – 1; pb_last = Lb->elem + Lb->length – 1; while(pa<=pa_last && pb<=pb_last) { if(Less_EqualList(pa,pb)) *pc++=*pa++; else *pc++=*pb++; } while(pa<=pa_last) *pc++=*pa++; while(pb<=pb_last) *pc++=*pb++; } |
顺序表的查找算法 |
int LocateElem(List *La,ElemType e,int type) { int i; switch (type) { case EQUAL: for(i=0;i<length;i++) if(EqualList(&La->elem[i],&e)) return 1; break; default: break; } return 0; } |
顺序表的联合算法 |
void UnionList(List *La, List *Lb) { int La_len,Lb_len; int i; ElemType e; La_len=ListLength(La); Lb_len=ListLength(Lb); for(i=0;i<Lb_len;i++) { GetElem(*Lb,i,&e); if(!LocateElem(La,e,EQUAL)) ListInsert(La,++La_len,e); } } |
线性表的链式表示与实现
掌握线性链表、单链表、静态链表的概念、表示及实现方法
线性链表之单链表的表示及实现方法。
线性链表的概念。
|
|
|
循环链表与双向链表
掌握循环链表的概念,掌握双向链表的的表示与实现
双向链表的表示与实现
双向链表的存储表示
Status ListDelete_DuL(DuLinkList &L,int i,ElemType &e){ if(!(p=GetElemP_DuL(L,i))) return ERROR; e=p->data; p->prior->next=p->next; p->next->prior=p->pror; free(p); return OK; }//ListDelete_DuL |
Status ListInsert_DuL(DuLinkList &L,int i,ElemType &e){ if(!(p=GetElemP_DuL(L,i))) return ERROR; if(!(s=(DuLinkList)malloc(sizeof(DuLNode)))) return ERROR; s->data=e; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s; return OK; }//ListInsert_DuL |
typedef struct LNode{ ElemType data; struct LNode *next; }*Link,*Position; typedef struct{ Link head,tail; int len; }LinkList; Status MakeNode(Link &p,ElemType e); //分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR void FreeNode(Link &p); //释放p所指结点 Status InitLinst(LinkList &L); //构造一个空的线性链表L Status DestroyLinst(LinkList &L); //销毁线性链表L,L不再存在 Status ClearList(LinkList &L); //将线性链表L重置为空表,并释放原链表的结点空间 Status InsFirst(Link h,Link s); //已知h指向线性链表的头结点,将s所指结点插入在第一个结点之前 Status DelFirst(Link h,Link &q); //已知h指向线性链表的头结点,删除链表中的第一个结点并以q返回 Status Append(LinkList &L,Link s); //将指针s所指(彼此以指针相链)的一串结点链接在线性链表L的最后一个结点 //之后,并改变链表L的尾指针指向新的尾结点 Status Remove(LinkList &L,Link &q); //删除线性链表L中的尾结点并以q返回,改变链表L的尾指针指向新的尾结点 Status InsBefore(LinkList &L,Link &p,Link s); //已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前, //并修改指针p指向新插入的结点 Status InsAfter(LinkList &L,Link &p,Link s); //已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后, //并修改指针p指向新插入的结点 Status SetCurElem(Link &p,ElemType e); //已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值 ElemType GetCurElem(Link p); //已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值 Status ListEmpty(LinkList L); //若线性链表L为空表,则返回TRUE,否则返回FALSE int ListLength(LinkList L); //返回线性链表L中的元素个数 Position GetHead(LinkList L); //返回线性链表L中头结点的位置 Position GetLast(LinkList L); //返回线性链表L中最后一个结点的位置 Position PriorPos(LinkList L,Link p); //已知p指向线性链表L中的一个结点,返回p所指结点的直接前趋的值 //若无前趋,返回NULL Position NextPos(LinkList L,Link p); //已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的值 //若无后继,返回NULL Status LocatePos(LinkList L,int i,Link &p); //返回p指示线性链表L中第i个结点的位置并返回OK,i值不合法时返回ERROR Position LocateElem(LinkList L,ElemType e, Status(*compare)(ElemType,ElemType)); //返回线性链表L中第1个与e满足函数compare()判定关系的元素的位置, //若下存在这样的元素,则返回NULL Status ListTraverse(LinkList L,Status(*visit)()); //依次对L的每个元素调用函数visit()。一旦visit()失败,则操作失败。 |
表尾进行插入或删除操作的线性表。
栈顶,表头称为
栈底,不含元素的空表称为
空栈。
ai|
ai
(- ElemSet,i=1,2,…,n,n>=0}
ai-1,
ai>|
ai-1,
ai
(- D,i=2,…,n}
栈的应用
掌握栈的应用方法,理解栈的重要作用
利用栈实现行编辑,利用栈实现表达式求值
利用栈实现表达式求值
10
=(102)
8
void conversion() { pSqStack S; SElemType e; int n; InitStack(&S); printf(“Input a number to convert to OCT:/n”); scanf(“%d”,&n); if(n<0) { printf(“/nThe number must be over 0.”); return;} if(!n) Push(S,0); while(n){ Push(S,n%8); n=n/8; } printf(“the result is: “); while(!StackEmpty(*S)){ Pop(S,&e); printf(“%d”,e);} } |
void LineEdit() { pSqStack S,T; char str[1000]; int strlen=0; char e; char ch; InitStack(&S); InitStack(&T); ch=getchar(); while(ch!=EOFILE) { while(ch!=EOFILE&&ch!=’/n’) { switch(ch){ case ‘#’: Pop(S,&ch); break; case ‘@’: ClearStack(S); break; default: Push(S,ch); break; } ch=getchar(); } if(ch==’/n’) Push(S,ch); while(!StackEmpty(*S)) { Pop(S,&e); Push(T,e); } while(!StackEmpty(*T)) { Pop(T,&e); str[strlen++]=e; } if(ch!=EOFILE) ch=getchar(); } str[strlen]=’/0′; printf(“/n%s”,str); DestroyStack(S); DestroyStack(T); } |
char EvaluateExpression() { SqStack *OPND,*OPTR; char c,x,theta; char a,b; InitStack(&OPTR); Push(OPTR,’#’); InitStack(&OPND); c=getchar(); while(c!=’#’||GetTop(*OPTR)!=’#’) { if(!In(c,OP)) {Push(OPND,c);c=getchar();} else switch(Precede(GetTop(*OPTR),c)) { case ‘<‘: Push(OPTR,c); c=getchar(); break; case ‘=’: Pop(OPTR,&x); c=getchar(); break; case ‘>’: Pop(OPTR,&theta); Pop(OPND,&b); Pop(OPND,&a); Push(OPND,Operate(a,theta,b)); break; } } c=GetTop(*OPND); DestroyStack(OPTR); DestroyStack(OPND); return c; } |
队列
掌握队列的类型定义,掌握链队列的表示与实现方法
链队列的表示与实现
链队列的表示与实现
是一种先进先出的线性表。它只允许在表的一端进行插入,而在另一端删除元素。象日常生活中的排队,最早入队的最早离开。
队尾
,允许删除的一端则称为
队头
。
链队列
。一个链队列显然需要两个分别指示队头和队尾的指针。
|
|
a1
a2…
an'(n>=0)
长度。零个字符的串称为
空串,它的长度为零。
子串。包含子串的串相应地称为
主串。通常称字符在序列中的称为该字符在串中的
位置。子串在主串中的位置则以子串的第一个字符在主串中的位置来表示。
ai|
ai(-CharacterSet,i=1,2,…,n,n>=0}
ai-1,
ai>|
ai-1,
ai(-D,i=2,…,n}
串的表示和实现
掌握串的几种实现方法
定长顺序存储表示法堆分配存储表示法
堆分配存储表示法
a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | … | a[n] |
3 | a | b | c | pascal |
a | b | c | /0 | c |
S1,S2串长和小于最大值 |
S1,S2串长和超过最大串长 |
S1串长已等于最大串长 |
串操作应用举例
掌握文本编辑的基本原理及方法
简单文本编辑
串的存储管理
图一 |
图二 |
串的查找
,
插入
和
删除
等基本操作。
main(){ float a,b,max; scanf(“%f,%f”,&a,&b); if (a>b) max=a; else max=b; }; |
m | a | i | n | ( | ) | { | /n | f | l | o | a | t | a | , | b | , | |||
m | a | x | ; | /n | s | c | a | n | f | ( | “ | % | f | , | % | f | “ | ||
, | & | a | , | & | b | ) | ; | /n | i | f | a | > | b | m | |||||
a | x | = | a | ; | /n | e | l | s | e | m | a | x | = | b | ; | ||||
/n | } | /n |
数组的顺序表示与实现
掌握数组的定义,数组的顺序表示方法
数组的定义,数组的顺序表示方法
数组的顺序表示方法
i
=0,…,b
i
-1,i=1,2,…,n;
a
j1j2…jn
|n(>0)称为数组的维数,b
i
是数组第i维的长度,j
i
是数组元素的第i维下标,
a
j1j2…jn
(-ElemSet}
1
,R
2
,…R
n
|
j1…ji…jn
,a
j1…ji+1 …jn
>|
k
<=b
k-1
,1<=k<=n且k<>i,
i
<=b
i-2
,a
j1…ji…jn
,
j1…ji+1 …jn
(-D,i=2,…n}
a 00 | a 01 | a 02 | … | a 0,n-1 |
a 10 | a 11 | a 12 | … | a 1,n-1 |
… | … | … | … | … |
a m-1,0 | a m-1,1 | a m-1,2 | … | a m-1,n-1 |
A 0 |
| ||||||||||||||||||||
A 1 | |||||||||||||||||||||
… | |||||||||||||||||||||
A m |
a 00 | a 01 | a 02 | … | a 0,n-1 | a 10 | a 11 | a 12 | … | a 1,n-1 | … | a m-1,0 | a m-1,1 | a m-1,2 | … | a m-1,n-1 |
=va_arg(ap,int);
ind
<0||ind>=A.bounds[i]) return OVERFLOW;
ind
;
原子和
子表,当广义表非空时,称第一个元素a1为LS的
表头称其余元素组成的广义表为
表尾.
树、二叉树定义及术语
掌握树、二叉树的基本概念和术语,二叉树的性质
二叉树的定义、二叉树的性质
二叉树的性质
结点
包含一个数据元素及若干指向其子树的分支。
度
。
叶子
或
终端结点
。
非终端结点
或
分支结点
。
孩子
,相应地,该结点称为孩子的
双亲
。
兄弟
。
祖先
是从根到该结点所经分支上的所有结点。
子孙
。
满二叉树
,如图(a),按图示给每个结点编号,如果有深度为k的,有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为
完全二叉树
。
性质1: | 在二叉树的第i层上至多有2的i-1次方个结点(i>=1)。 | |
性质2: | 深度为k的二叉树至多有2的k次方减1个结点(k>=1)。 | |
性质3: | 对任何一棵二叉树T,如果其终端结点数为n 0 ,度为2的结点数为n 2 ,则n 0 =n 2 +1。 | |
性质4: | 具有n个结点的完全二叉树的深度为|log 2 n |+1 | |
性质5: | 如果对一棵有n个结点的完全二叉树的结点按层序编号,则对任一结点i(1=<i=<n)有: (1)如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则双亲PARENT(i)是结点i/2 (2)如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i (3)如果2i+1>n,则结点i无右孩子;否则其右孩子RCHILD(i)是结点2i+1 |
二叉树的存储结构
掌握二叉树的两种存储结构
链式存储结构
链式存储二叉树的基本操作
结点编号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
结点值 | 1 | 2 | 3 | 4 | 5 | 0 | 0 | 0 | 0 | 6 | 7 | 0 | 0 | 0 | 0 |
遍历二叉树
掌握二叉树遍历的三种方法
二叉树的遍历算法
中序与后序遍历的非递归算法
先序 | 1 | 访问根结点 |
2 | 先序访问左子树 | |
3 | 先序访问右子树 | |
中序 | 1 | 中序访问左子树 |
2 | 中序访问根结点 | |
3 | 中序访问右子树 | |
后序 | 1 | 后序访问左子树 |
2 | 后序访问右子树 | |
3 | 访问根结点 |
基本数据结构有____,____,____,____四种。
存储结构可根据数据元素在机器中的位置是否连续分为____,____。
算法的基本要求有_____,_____,____,____。
度量算法效率可通过_______,_______两方面进行。
栈的定义:_______________________。
举例说明数据对象、数据元素、数据项的定义。
类C语言和C语言有哪些主要区别?
线性表的基本操作有哪些?
写出类C语言定义的线性表的静态分配顺序存储结构。
下面是线性表的存储结构和插入算法,请补充算法中空缺部分。
下面是栈的顺序存储结构和入栈、出栈算法,请补充算法中空缺部分。
用图示法说明在单向线性链表中插入结点的过程。
有一学生成绩单,画出用链式存储结构时的成绩单数据的存储映像。
用C语言实现单向线性链表。写出存储结构定义及基本算法。
图的定义与术语
掌握图的定义及常用术语
图的常用术语
图的常用术语
完全图
。
有向完全图
。
稀疏图
,反之称为
稠密图
。
v1与v2互为邻接点 e1依附于顶点v1和v2 v1和v2相关联 v1的度为3 |
图的存储结构
掌握图的二种存储表示方法
图的数组表示及邻接表表示法
邻接表表示法
表结点 |
| |||
头结点 |
|
静态查找表(一)顺序表的查找
掌握查找的基本概念,顺序表查找的性能分析
查找的基本概念
顺序表查找的性能分析
查找表: | 是由同一类型的数据元素(或记录)构成的集合。 |
查找表的操作: | 1、查询某个“特定的”数据元素是否在查找表中。 2、检索某个“特定的”数据元素的各种属性。 3、在查找表中插入一个数据元素; 4、从查找表中刪去某个数据元素。 |
静态查找表 | 对查找表只作前两种操作 |
动态查找表 | 在查找过程中查找表元素集合动态改变 |
关键字 | 是数据元素(或记录)中某个数据项的值 |
主关键字 | 可以唯一的地标识一个记录 |
次关键字 | 用以识别若干记录 |
查找 | 根据给定的某个值,在查找表中确定一个其关键字等于给定的记录或数据元素。若表中存在这样的一个记录,则称 查找是成功的 ,此时查找的结果为给出整个记录的信息,或指示该记录在查找表中的位置;若表中不存在关键字等于给定值的记录,则称 查找不成功 。 |
典型的关键字类型说明: |
typedef float KeyType;//实型 typedef int KeyType;//整型 typedef char *KeyType;//字符串型 |
数据元素类型定义为: |
typedef struct{ KeyType key; // 关键字域 … }ElemType; |
对两个关键字的比较约定为如下的宏定义: |
对数值型关键字 #define EQ(a,b) ((a)==(b)) #define LT(a,b) ((a)<(b)) #define LQ(a,b) ((a)<=(b)) 对字符串型关键字 #define EQ(a,b) (!strcmp((a),(b))) #define LT(a,b) (strcmp((a),(b))<0) #define LQ(a,b) (strcmp((a),(b))<=0) |
ADT StaticSearchTable{ 数据对象D:D是具有相同特性的数据元素的集合。各个数据元素均含有类型相同,可唯一标识数据元素的关键字。 数据关系R:数据元素同属一个集合。 基本操作P: Create(&ST,n); 操作结果:构造一个含n个数据元素的静态查找表ST。 Destroy(&ST); 初始条件:静态查找表ST存在。 操作结果:销毁表ST。 Search(ST,key); 初始条件:静态查找表ST存在,key为和关键字类型相同的给定值。 操作结果:若ST中在在其关键字等于key的数据元素,则函数值为该元素的值或在表中的位置,否则为“空”。 Traverse(ST,Visit()); 初始条件:静态查找表ST存在,Visit是对元素操作的应用函数。 操作结果:按某种次序对ST的每个元素调用函数visit()一次且仅一次。一旦visit()失败,则操作失败。 }ADT StaticSearchTable |
SSTable ST
,KeyType key){
其中:Pi为查找表中第i个记录的概率,且 Ci为找到表中其关键字与给定值相等的第i个记录时,和给定值已进行过比较的关键字个数。 | |
等概率条件下有: | |
假设查找成功与不成功的概率相同: |
哈希表(一)
掌握哈希表的概念作用及意义,哈希表的构造方法
哈希表的构造方法
哈希表的构造方法
以学生学号为关键字
的成绩表,1号学生的记录位置在第一条,10号学生的记录位置在第10条…
a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
刘丽 | 刘宏英 | 吴军 | 吴小艳 | 李秋梅 | 陈伟 | … | |
姓名中各字拼音首字母 | ll | lhy | wj | wxy | lqm | cw | … |
用所有首字母编号值相加求和 | 24 | 46 | 33 | 72 | 42 | 26 | … |
最小值可能为3 最大值可能为78 可放75个学生 |
成绩一 | 成绩二… | ||
3 | … | ||
… | … | ||
24 | 刘丽 | 82 | 95 |
25 | … | ||
26 | 陈伟 | ||
… | … | ||
33 | 吴军 | ||
… | … | ||
42 | 李秋梅 | ||
… | … | ||
46 | 刘宏英 | ||
… | … | ||
72 | 吴小艳 | ||
… | … | ||
78 | … |
哈希表
。
冲突
现象:对不同的关键字可能得到同一哈希地址。
地址 | 01 | 02 | … | 25 | 26 | 27 | … | 100 |
年龄 | 1 | 2 | … | 25 | 26 | 27 | … | … |
人数 | 3000 | 2000 | … | 1050 | … | … | … | … |
… |
75.11.23
76.03.02
76.07.12
75.04.21
76.02.15
…
5864 | 5864 | ||
4220 | 0224 | ||
+) | 04 | +) | 04 |
———– | ———– | ||
10088 | 6092 | ||
H(key)=0088 | H(key)=6092 | ||
(a)移位叠加 | (b)间界叠加 |
哈希表(二)
掌握哈希表处理冲突的方法及哈希表的查找算法
哈希表处理冲突的方法
开放定址法
成绩一 | 成绩二… | ||
3 | … | ||
… | … | ||
24 | 刘丽 | 82 | 95 |
25 | … | ||
26 | 陈伟 | ||
… | … | ||
33 | 吴军 | ||
… | … | ||
42 | 李秋梅 | ||
… | … | ||
46 | 刘宏英 | ||
… | … | ||
72 | 吴小艳 | ||
… | … | ||
78 | … |
线性探测再散列
。
二次探测再散列
。
伪随机数列
。称
伪随机探测再散列
。
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
60 | 17 | 29 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
60 | 17 | 29 | 38 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
60 | 17 | 29 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
38 | 60 | 17 | 29 |
插入排序,快速排序
掌握排序的基本概念,插入排序、快速排序的算法
插入排序、快速排序的算法
快速排序算法
:将一个数据元素的无序序列重新排列成一个按关键字有序的序列。
姓名 | 年龄 | 体重 |
1李由 | 57 | 62 |
2王天 | 54 | 76 |
3七大 | 24 | 75 |
4张强 | 24 | 72 |
5陈华 | 24 | 53 |
姓名 | 年龄 | 体重 |
3七大 | 24 | 75 |
4张强 | 24 | 72 |
5陈华 | 24 | 53 |
2王天 | 54 | 76 |
1李由 | 57 | 62 |
稳定的
!
姓名 | 年龄 | 体重 |
4张强 | 24 | 72 |
3七大 | 24 | 75 |
5陈华 | 24 | 53 |
2王天 | 54 | 76 |
1李由 | 57 | 62 |
不稳定的
!
38 | 49 | 65 | 97 | 76 | 13 | 27 | 49 | … |
38 | 49 | 65 | 76 | 97 | 13 | 27 | 49 | … |
13 | 38 | 49 | 65 | 76 | 97 | 27 | 49 | … |
13 | 27 | 38 | 49 | 65 | 76 | 97 | 49 | … |
13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 | … |
49 | 38 | 65 | 97 | 78 | 13 | 27 | 49 | … |
i=1 | 49 | |||||||
first | ||||||||
i=2 | 49 | 38 | ||||||
final | first | |||||||
i=3 | 49 | 65 | 38 | |||||
final | first | |||||||
i=4 | 49 | 65 | 97 | 38 | ||||
final | first | |||||||
i=5 | 49 | 65 | 76 | 97 | 38 | |||
final | first | |||||||
i=6 | 49 | 65 | 76 | 97 | 13 | 38 | ||
final | first | |||||||
i=7 | 49 | 65 | 76 | 97 | 13 | 27 | 38 | |
final | first | |||||||
i=8 | 49 | 49 | 65 | 76 | 97 | 13 | 27 | 38 |
final | first |
49 | 38 | 38 | 38 | 38 | 13 | 13 |
38 | 49 | 49 | 49 | 13 | 27 | 27 |
65 | 65 | 65 | 13 | 27 | 38 | 38 |
97 | 76 | 13 | 27 | 49 | 49 | |
76 | 13 | 27 | 49 | 49 | ||
13 | 27 | 49 | 65 | |||
27 | 49 | 78 | ||||
49 | 97 | |||||
初始 | 第一趟 | 第二趟 | 第三趟 | 第四趟 | 第五趟 | 第六趟 |
初始关键字 | 49 | 38 | 65 | 97 | 76 | 13 | 27 | 49 |
i | j | j | ||||||
1次交换之后 | 27 | 38 | 65 | 97 | 76 | 13 | 49 | |
i | i | j | ||||||
2次交换之后 | 27 | 38 | 97 | 76 | 13 | 65 | 49 | |
i | j | j | ||||||
3次交换之后 | 27 | 38 | 13 | 97 | 76 | 65 | 49 | |
i | i | j | ||||||
4次交换之后 | 27 | 38 | 13 | 76 | 97 | 65 | 49 | |
ij | j | |||||||
完成一趟排序 | 27 | 38 | 13 | 49 | 76 | 97 | 65 | 49 |
初始状态 | 49 | 38 | 65 | 97 | 76 | 13 | 27 | 49 |
一次划分 | 27 | 38 | 13 | 49 | 76 | 97 | 65 | 49 |
分别进行 | 13 | 27 | 38 | |||||
结束 | 结束 | 49 | 65 | 76 | 97 | |||
49 | 65 | 结束 | ||||||
结束 | ||||||||
有序序列 | 13 | 27 | 38 | 49 | 49 | 65 | 76 | 97 |
文件概念,顺序文件
掌握文件基本概念,顺序文件的概念。
文件基本概念
逻辑结构与物理结构的关系。
:是由大量性质相同的记录组成的集合。
文件按记录类型不同分类 | 操作系统的文件 | 一维的连续的字符序列 | |||||||||||||||||||||||||||||||||||
数据库文件 | 带有结构的记录的集合,每条记录是由一个或多个数据项组成的集合。
|
文件按记录长度是否相同分类 | 定长记录文件 | 文件中每个记录含有信息长度相同。 |
不定长记录文件 | 文件中每个记录含有信息长度不等。 |
逻辑结构
是指记录在用户或应用程序员面前呈现的方式,是用户对数据的表示和存取方式。
姓名 | 准考证号 | 政治 | 语文 | 数学 | 外语 |
刘青 | 1501 | 78 | 90 | 100 | 95 |
张朋 | 1502 | 64 | 88 | 90 | 74 |
崔永 | 1503 | 90 | 100 | 85 | 89 |
郑琳 | 1504 | 85 | 73 | 90 | 91 |
… |
物理结构
是数据在物理存储器上存储的方式。一条物理记录指的是计算机用一条I/O命令进行读写的基本数据单位。
索引文件
掌握索引文件的有关概念
索引文件的基本概念,索引文件的重要意义
索引文件的建立
索引表
。
索引顺序文件
。反之,若数据区中记录不按关键字顺序排列,则称
非顺序文件
。
物理记录号 | 姓名 | 年龄 | 体重(关键字) |
1 | 李由 | 57 | 62 |
2 | 王天 | 54 | 76 |
3 | 七大 | 24 | 75 |
4 | 张强 | 24 | 72 |
5 | 陈华 | 24 | 53 |
体重(关键字) | 物理记录号 |
53 | 5 |
62 | 1 |
72 | 4 |
75 | 3 |
76 | 2 |
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/156913.html