本文根据哔哩哔哩王卓老师学习而写的一些,具体视频可看数据结构与算法基础(青岛大学-王卓)_哔哩哔哩_bilibili
线性表
一般线性表的模板
线性表分为两种,一种为顺序表,一种为链表,两个各有各的优缺点
顺序表的模板如下:
分为静态分配和动态分配两种
//静态分配
typedef struct
{
int elem[LIST_INIT_SIZE];//地址
int length;//实际变量个数
}SqList;//定义顺序表类型(与java中的class比较类似
//动态分配
typedef struct{
ElemType *data;//(存放第一个元素地址)
int length;
}SqList;
具体使用方法
关于使用进行逐步解析,如下:
SqList L;
L.data = (ElemType*)malloc(sizeof(ElemType)*MaxSize)
//ElemType规定划定类型是int or double or char等等;
//ElemType*即为指针,同于data;
//(ElemType*)强制转换
//sizeof(ElemType)类型长度
//sizeof(ElemType)*MaxSize类型长度乘以最大数
函数解析
需要头文件<stdlib.h>
malloc(m):开辟m字节长度的地址空间,并且返回空间首地址
free(p):释放指针p所指的变量的存储空间,彻底删除一个变量
C++的动态分配
new 类型名T(初值列表)-> int*p1 = new int;or int*p1 = new int(10);
//功能:申请用于存放T类型对象的内存空间,并依初始只列表赋以初值结果
delete 指针p
//释放空间;
C++中的参数传递
(1)类型,个数,顺序一致
(2)传值方式:
a.传值方式(实参)//二者使用的不同地址
b.传地址(形参与实参同一地址)
参数为指针变量
参数为引用类型
参数为数组名
传地址方式 —— 数组名作参数
传递的是数组的首地址
对形参数组所做的任何改变都将反映到实参数组中
#include<iostream.h>
void main(){
char a[10] = "hello";
sub(a);
cout<<a<<endl;
}
void sub(char b[]){
b[] = "world";
}//输出的是world
引用类型作参数(更为推荐!)
即是给一个对象替代的名字
#include<iostream.h>
void main(){
int i = 5;
int &j = i;//引用型
i = 7;
cout<<"i = " <<i<<"j ="<<j;
}//输出i = 7,j = 7
线性表的一些操作
查找算法
顺序查找法:按值查找,有就输出第几个元素,没有就输出0
具体操作:从表的一端开始,逐个比较,找到返回位置序号,未找到,返回0
int LocateElem(SqList ElemType e){
//查找值为e的元素
for(i = 0;i<L.length,i++){
if(L.elem[i] = e)
return i+1;
}
return 0;
}
ASL平均查找长度:为确定记录在表中的位置,需要与给定值比较的关键字的个数的期望值,叫做查找算法的平均查找长度
插入算法
线性表的插入->顺序表的插入(时间复杂度:O(n))
- 插入位置在最后 ->直接放到最后一个数组
- 插入位置在中间 ->从后往前,依次往后搬
- 插入位置在最前面 ->同上
考虑两种异常情况:
- 若有n个元素,则只可插入0~n+1的位置,若给出的不在范围内,则异常
- 线性表元素已经满了,称为溢出->判断L.length的大小
算法思想:
- 判断插入位置是否合法
- 判断储存空间是否满了,若满了返回ERROR;
- ......
Status Lislinsert_Sq(SqList &L,int i.ElemType e){
if(i<1 || i > L.length + 1)//i值不合法
return ERROR;
if(L.length == MAXSIZE)//储存空间已满
return ERROR;
for(j = L.length - 1;j >=i - 1;j--)
L.elem[j+1] = L.elem[j];
L.elem[i - 1] = e;
L.length++;
return OK;
}
算法时间主要耗费在移动元素的操作上
- 若在尾结点,无需移动
- 若在首节点,全往后移
删除算法
顺序表的删除
- (1)删除位置在最后
- (2)删除位置在中间 ->把后面的元素往前移动
- (3)删除位置在最前面 ->从前往后,把后面的元素往前移动
算法思想:
- 判断删除位置i是否合法
- 将欲删除的元素保留在e中(可省略)
- 将i+1至n位的元素依次向前移动一个位置
- 表长减一,删除成功返回OK
Status ListDelete_Sq(SqList &L,int i){
if((i<1)||(i >L.length))
return ERROR;
for(j = 1;j < L.length;j++)
L.elem[j-1] = L.elem[j];
L.length--;
return OK;
}
额外的其他算法
- 线性表的初始化
//InitList_Sq(顺序存储的)
Status InitList_Sq(SqList &L){
L.elem = new ElemType[MAXSIZE];
if(!.elem)//进行逻辑非运算,若有内容则为假
{
exit(OVERFLOW);//OVERFLOW -2
}
L.length = 0;
return OK;//初始化成功放回1
//OK 1
}
- 销毁线性表
void DestroyList(Sqlist &L){
if(L.elem)//若有则为真
delete L.elem;
}
- 清空线性表
void ClearList(SqList &L){
L.length = 0;//将线性表长度设置为0
}
- 求线性表的长度
int GetLength(SqList L){
return(L.length);
}
- 判断线性表L是否为空
int IsEmpty(SqList L){
if(L.length == 0)
return 1;
else return 0;
}
- 顺序表的取值(随机存取)
int GetElem(SqList L,int i,ElemType &e){
if(i<1||i > L.length)
return ERROR;
//异常判断
e = L.elem[i - 1];
return OK;
}
举例
图书管理项目
#include<stdio.h>
#define MAXSIZE 100;
//类比java里的class
typedef struct book //每本书的信息
{
char no[20];//ISBN码
char name[50];//图书名字
float price;//图书价格
}Book;
//链表(结构体)
typedef struct
{
Book *elem;
int length;
}SqList;
学校老师提供的一个线性表的代码
#include<stdio.h>
#include<stdlib.h>
//定义顺序表的元素类型为整型
//最大长度为50
typedef int ElemType;//定义ElemType为整型
#define MAXSIZE 50
//顺序表的结构体类型以及命名为SeqList
//包含了一个长度为50的()类型数组
//以及一个整型变量last记录长度
typedef struct
{
ElemType data[MAXSIZE];
int last;
}SeqList;
//创建了一个函数
SeqList* CreatSeqList()//前面是返回类型 后面是名称
{
//动态分配内存空间
//指针变量
SeqList *head=(SeqList *)malloc(sizeof(SeqList));
//把last赋值为-1
head->last=-1;
int x;
//输入-1视为结束
printf("input the element of the list, -1 is end\n");
scanf("%d",&x);//输入
//每输入一个数不为-1的时候last都加1
//把输入的数x赋值到data[last]里面
//再输入下一个数
while(x != -1 && head->last < MAXSIZE) {
head->last++;
head->data[head->last] = x;
scanf("%d",&x);
}
return head;//最后返回头指针
}
//显示所有元素
void ShowSeqList(SeqList *L)
{
// SeqList *p=L;
for(int i = 0; i <= L->last; i++)//遍历数组
printf("%d ",L->data[i]);
}
int Locate(SeqList *L, ElemType e) {
//todo, 编写查找运算的代码
}
int InsList(SeqList *L,int i,ElemType e) {
//todo, 编写插入运算的代码
}
int DelList(SeqList *L,int i, ElemType *e) {
//todo, 编写删除运算的代码
}
int main()
{
SeqList *L;//定义L的指针
L = CreatSeqList();//L的指针指向结构体
ShowSeqList(L);
//todo, 测试查找运算
//todo, 测试插入运算
//todo, 测试删除运算
return 1;
}