文章预览:
数据结构与算法基础-王卓
第一章绪论
1.1.1基本概念和术语
-
数据
- 是能输入计算机且能被计算机处理的各种符号的集合
-
数据元素
-
数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理
-
如下表格则为数据,第二行则为数据元素
-
也称为元素、记录、结点、或顶点
班级 姓名 年龄 23.1 张三 21 20.7 王五 20 19.7 李四 22
-
-
数据项
- 构成数据元素的不可分割的最小单位,表格中的张三即数据项
-
数据对象
-
性质相同的数据元素的集合,是数据的一个子集
例如:
- 整数数据对象是集合N={0,+1,-1,+2,-2,…}
- 学籍表也可看作一个数据对象,性质相同的数据元素即可看作为数据对象
-
1.1.2基本概念和术语
1.数据结构解释
- 数据元素相互之间的关系称为结构
- 是指相互之间存在一种或多种特定关系的数据元素集合
2.数据结构包括三方面内容
- 数据元素之间的逻辑关系,也称为逻辑结构
- 数据元素及其关系在计算机内存中的表示,称为数据的存储结构
- 数据的运算和实现
3.数据结构的两个层次
-
逻辑结构
-
存储结构
3.1逻辑结构与存储结构的关系:
- 存储结构是逻辑关系的映像与元素本身的映像
- 逻辑结构是数据结构的抽象,存储结构是数据结构的实现
- 两者综合起来,建立了数据元素之间的结构关系
3.1.1逻辑结构
(1)线性结构
一个前驱,一个后继
(2)非线性结构
一对多
3.1.2四种存储结构
- 顺序存储结构
- 链式存储结构
- 索引存储结构(了解)
- 散列存储结构(了解)
1.1.3数据类型和抽象数据类型
概念小结:
第二章 线性表
2.1类c语言有关操作补充1
2.1.1补充:元素类型说明
顺序表类型定义:
typedef struct{
ElemType data[];
int length;
}SqList;//顺序表类型
说明:
ElemType 在这里代表元素类型的意思,无实际意义,当实际情况中知道类型,就可加上 下面的代码:
typedef char ElemType;//假如已知元素类型为char型
如果表中元素类型不单一,则可用以下方式(即把上述代码拆分为两块:
typedef struct{
float p;
int e;
}Polynomial;
typedef struct{
Polynomial *elem;//首地址,elem保存地址
int length;
}SqList;
2.1.2补充:数组定义
-
定义方式一:数组静态分配
typedef struct{ ElemType data[MaxSize]; int length; }SqList;//顺序表类型
-
定义方式二:数组动态分配(上述元素有多个类型,即使用的是动态分配方式定义数组的)
typedef struct{ ElemType *data;//数组首地址 int length; }SqList;//顺序表类型
这种方式我们不知道内存到底有多大,接下来将用内存分配函数来分配空间:
SqList L;//L就是要操作的顺序表,即SqList L.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize);
2.1.3 C语言的内存动态分配
-
malloc(m)函数,开辟m字节长度的地址空间,并返回这段空间的首地址
-
sizeof(x)运算,计算变量x的长度,即变量需占的字节数*变量个数
-
L.data是数组的首地址(无空间),ElemType*使新分配的空间首地址的元素类型为数组的元素类型,
一个“=”就能将放置数组元素类型的空间分配给L了
-
free§函数,释放指针p所指变量的存储空间,即彻底删除一个变量
2.1.4补充:C++的动态存储分配(相比C的动态分配更简单)
new 类型名T(初值列表)
功能:
申请用于存放T类型对象的内存空间,并依初值列表赋以初值
结果值:
成功:T类型的指针,指向新分配的内存
成功:0(NULL)
int *p1 = new int;//或 int *p1 = new int(10)
delete 指针P
功能:
释放指针P所指向的内存。P必须是new操作的返回值
2.2类C语言有关操作补充2
2.1.1 C++的参数传递
-
传值方式(参数为整型、实型、字符型等)
#include<iostream.h> void swap(float m,float n) { float temp; temp = m; m = n; n = temp; } void main() { float a,b; cin>>a>>b; swap(a,b); cout<<a<<endl<<b<<endl; }
说明:函数修改的是形参的值,释放空间后,形参释放,实参的值不变
-
传地址
-
参数为指针变量
-
形参变化影响实参
#include<iostream.h> void swap(float *m,float *n) { float t; t = *m; *m = *n; *n = t;指交换m和n所指的内容 } void main() { float a,b,*p1,*p2; cin>>a>>b; p1 = &a;p2 = &b;//p1、p2分别指向变量a、b swap(p1,p2); cout<<a<<endl<<b<<e
-
形参变化不影响实参
#include<iostream.h> void swap(float *m,float *n){ float *t; t = m; m = n; n = t;//交换的是m和n指向的地址不是地址中的内容 } void main() { float a,b,*p1,*p2; cin>>a>>b; p1 = &a;p2 = &b; swap(p1,p2); cout<<a<<endl<<b<<e
-
-
参数为引用变量(引用,即给一个对象提供一个替代的名字)
#include<iostream.h> void main(){ int i = 5; int &j = i; i = 7;//公用同一个空间,但是同时有i、j两个名字,因此改变一个值时,另一个值也会改变 cout<<"i = "<<i<<"j"<<j; }
-
参数为数组名(传递的是数组的首地址,对形参数组所做的任何改变都将反映到实参数组中)
#include<iostream.h> void sub(char b[]){ b[] = "world"; } void main(void){ char a[10] = "hello"; sub(a); cout<<a<<endl; }
-
2.3线性表基本操作的实现
2.3.1线性表的基本操作
-
线性表的基本操作
- InitList(&L)
- DestroyList(&L)
- ClearList(&L)
- ListInsert(&L,i,e)
- ListDelete(&L,i,&e) //删除线性表L中第i个位置元素,用e返回
- IsEmpty(L)
- ListLength(L)
- LocateElem(L,e) //L中查找与给定值e相等的元素,若成功返回该元素在表中的序号,否则返回0
- GetElem(L,i,&e) //将线性表L中的第i个位置元素返回给e
-
补充:操作算法中用到的预定义常量和类型
//函数结果为状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;
2.3.2顺序表基本操作的实现
-
线性表L的初始化(参数用引用)
Status InitList_Sq(SqList &L){ L.elem = new ElemType[MAXSIZE]; if(!L.elem) exit(OVERFLOW); L.length = 0; return 0; }
-
顺序表的查找
int LocateElem(SqList L,ElemType e){ //在线性表中查找值为e的数据元素,返回其序号(是第几个元素) for(i = 0;i<L.length;i++) if(L.elem[i] = e) return i+1; return 0; }
-
顺序表的插入
算法的思想:
- 判断插入位置i是否合法
- 判断顺序表存储空间是否已满,若已满返回ERROR
- 将第n至第i位的元素依次向后移动一个位置,空出第i个位置
- 将要插入的新元素e放入第i个位置
- 表长加1,插入成功返回OK
Status ListInsert_SqList(&L,int i,ElemType e){ if(i<1||i>L.length+1)return ERROR;// 1 i值不合法 if(L.length==MAXSIZE)return ERROR;// 2 当前存储空间已满 for(j=L.length-1;j>=i-1;j--) L.elem[j+1]=L.elem[j];// 3 插入位置及以后的元素后移 L.elem[i-1]=e;// 4 将新元素e放入第i个位置 L.length++;// 5 表长增1 return OK; }
-
顺序表的删除
算法思想:
- 判断删除位置i是否合法(合法值为1<=i<=n)
- 将欲删除的元素保留在e中
- 将第i+1至第n位的元素依次向前移动一个位置
- 表长减1,删除成功返回OK
Status ListDelete Sq(SqList &L,int i){ if((i<1)||(i>L.length)) return ERROR;// 1 i值不合法 for(j=j;j<=L.length-1;j++) L.elem[j-1]=L.elem[j]; // 2 被删除元素之后的元素前移 L.length--; // 3 表长减1 return 0; }