笔记:数据结构篇
线性表
顺序表
知识点
1:线性表(linear list)是具有相同特征的数据元素的一个有限序列。
2:线性表用二元组(D,R)
D={ai|1<=i<=n,ai为ElemType类型}
R={r}
r={<a,ai+1>|1<=i<=n-1}
3:线性表具有以下特征
(1)有穷性:一个线性表中的元素个数是有限的
(2)一致性:一个线性表所有的元素的性质具有相同的
(3)序列性:一个系线性表中所有的元素之间相对位置是线性的,
各元素的位置只取决于它们的序号,所以一个线性表中可以存在两个相同的值
以下为顺序表基本运算
void initList(linearList * &L); // 初始化一个空的线性表
void createList(linearList * &L, ElemType data[], int n) // 自动确定长度的初始化方法
void destroyList(linearList * &L); // 销毁线性表并释放其所存储的空间
bool insertElem(linearList * &L, int i, ElemType el); // 在第 i 个位置插入 el 元素,i 不正确或空间不足返回false.
// bool insertElem(linearList * &L, int i, ElemType * el); // insertElem 方法的重载
bool deleteElem(linearList * &L, int i, ElemType &el); // 删除第 i 个元素,并用 el 返回其值
// deleteElem(linearList * &L, int i); // deleteElem 方法的重载
// 以下方法只读取数据无需改实参值的引用传递
bool listEmpty(linearList * L); // @return [Bool] 线性表是否为空
int listLength(linearList * L); // 返回线性表(数据的)的长度
void printList(linearList * L); // (控制台)打印线性表
bool getElem(linearList * L, int index, ElemType &el); // 获取线性表中引索为 index 的元素的值,引用赋值到传入el
的实参上,越界时返回false
// void getElem(linearList * L, int index, ElemType * el); // getElem 方法的重载,指针赋值给 ElemType 的数据类型(理论更省空间)
int locateElem(linearList * L, ElemType el); // 顺序查找第一个线性表数据中第一个和 el 相等的数据的引索,没有找到则返回-1
// void locateElem(linearList * L, ElemType * el); // locateElem 方法的重载,指针操作 ElemType 的数据类型(理论更省空间)
void CreateList(SqList*&L,ELemType a[],int n) | 建立由n个元素组成顺序表 |
---|---|
void InitList(SqList *&L) | 初始化线性表 |
DestroyList(SqList *&L) | 销毁线性表 |
bool ListEmpty(SqList *L) | 判段是否是空表 |
int ListLength(Sqlist *L) | 求线性表长度 |
void DispList(SqList *L) | 输出线性表 |
bool GetElem(L,i,ElemType&e) | 求线性表中的某个数据元素值 |
bool LocateElem(SqList *L.ElemType e) | 按元素值查找 |
bool ListInsert(SqList *&L,int i,ElemType e) | 插入数据元素 |
bool ListDelete(&L,i,&e) | 删除数据元素 |
以下为我的代码实现
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 20
/*
void CreateList(SqList*&L,ELemType a[],int n) //建立由n个元素组成顺序表
void InitList(SqList *&L) //初始化线性表
DestroyList(SqList *&L) // 销毁线性表
bool ListEmpty(SqList *L) // 判段是否是空表
int ListLength(Sqlist *L) // 求线性表长度
void DispList(SqList *L) //输出线性表
bool GetElem(L,i,ElemType&e) // 求线性表中的某个数据元素值
bool LocateElem(SqList *L.ElemType e) // 按元素值查找
bool ListInsert(SqList *&L,int i,ElemType e) // 插入数据元素
bool ListDelete(&L,i,&e) //删除数据元素
*/
typedef int ElemType;
typedef struct
{
ElemType data[MaxSize];
ElemType *elem;//存放线性表中的元素
int length; //存放线性表的长度
} SqList; //顺序表的类型
void InitList(SqList * &L)
{
L = (SqList * )malloc(sizeof(SqList));//分配存放线性表的空间
L->length = 0; //置空线性表的长度为0
}
void CreateList(SqList *&L,ElemType a[],int n)
{
int i = 0,k=0; //k表示L中元素的个数
L = (SqList * )malloc(sizeof(SqList)); //分配存放线性表的空间
while(i<n) //扫描数组a中的元素,并且将a[i]中的元素存放到L中
{
L->data[k] = a[i];
k++;i++;
}
L->length = k; //设置L的长度为k
}
void DestoryList(SqList * &L)
{
free(L);
}
bool ListEmpty(SqList * L)
{
return (L ->length==0);
}
int ListLength(SqList * L)
{
return(L->length);
}
void DispList(SqList * L)
{
for(int i=0;i<L -> length;i++)
printf("%d",L->data[i]);
printf("\n");
}
bool GetElem(SqList * L,int i,ElemType &e)
{
if(i<1||i>L->length)
return false;
e = L->data[i];
return true;
}
int LocateElem(SqList *L,ElemType e)
{
int i = 0;
while(i<L->length &&L->data[i]!=e)
i++;
if(i>=L->length)
return 0;
else
return i+1;
}
bool ListInsert(SqList *&L,int i,ElemType e)
{
/*int j;
if(i<1|| i>L->length +1||L->length ==MaxSize)
return false;
i--;
for(j=L->length;j>i;j--)
L->data[j]=L->data[j-1];
L ->data[i] = e;
L ->length++;
return true;*/
//1.检查插入的位置是否合法
int j=0;
if (L->length>=MaxSize) {
printf("移除\n");
return 0;
}else if (i<1||i>L->length+1) {
printf("插入位置不正确\n");
return 0;
} else {
for (j=L->length-1; j>=i-1; j--)
//2.插入位置以后的所有元素依次后移
L->data[j+1]=L->data[j];
//3.将元素x置入到下标i-1的位置
L->data[i-1]=e;
//4.将表的长度加1
L->length=L->length+1;
return 1;
}
}
bool ListDelete(SqList *&L,int i,ElemType &e)
{
int j;
if(i<1 || i>L->length)
return false;
i--;
e=L->data[i];
for(j=i;j<L->length-1;j++)
L->data[i] = L ->data[j+1];
L->length--;
return true;
}
/*
//重建法:合并A,B中元素,先将A中的元素放入C中,再将B中与A不同的元素放入C中
void Union1(SqList *A,SqList *B,SqList *&C)//有序顺序表表示集合,求集合的并
{
int i,lena;
ElemType e;
for(i=1;i<=ListLength(A);i++)
{
GetElem(A,i,e);
ListInsert(C,i,e);
}
lena=ListLength(A);
for(i=1;i<=ListLength(B);i++)
{
GetElem(B,i,e);
if(!LocateElem(A,e))
ListInsert(C,++lena,e);
}
}*/
void DispalyElem(SqList *l)
{
for(int i=0;i<l->length;i++)
printf("%d ",l->elem[i]);
printf("\n");
}
/*void Union(SqList *A,SqList *B,SqList *&C)
{
printf("求线性表的并集\n");
int i=0,j=0,k=0;
int a,b;
while((i<=A->length-1)&&(j<=B->length-1))
{
GetElem(A,i,a);
GetElem(B,j,b);
if(a<=b)//给元素排序,并且存到C中
{
C->elem[k++]=A->elem[i++];
}
else
{
C->elem[k++]=B->elem[j++];
}
}
while(i<=A->length-1)
{
GetElem(A,i,a);
C->elem[k++]=A->elem[i++];
}
while(j<=B->length-1)
{
GetElem(B,j,b);
C->elem[k++]=B->elem[j++];
}
C->length=k;
}*/
int main()
{
SqList *L;
int a[]={0,2,3,4,5,6,7,8,9,0};
CreateList(L,a,10);
DispList(L);
int sucess = ListInsert(L,10,10);
if(sucess)
{
printf("插入成功\n");
}
else
{
printf("插入失败\n");
}
DispList(L);
DestoryList(L);
system("pause");
/* SqList *A,*B,*C;
InitList(A);//初始化线性表A;
InitList(B);//初始化线性表B;
printf("输入线性表A元素个数:\n");
scanf("%d",&A->length);
printf("输入线性表A中的元素:\n");
for(int j=0;j<A->length;j++)
{
scanf("%d",&A->data[j]);
}
printf("输入线性表B元素个数:\n");
scanf("%d",&B->length);
printf("输入线性表B中的元素:\n");
for(int j=0;j<B->length;j++)
{
scanf("%d",&B->data[j]);
}
Union(A,B,C);
DispalyElem(C);
return 0;*/
}
总结:几次运行失败的原因,
1:没有理解线性表的结构
2:没有理解里面参数的实际意义如*,&
3:运行使用的数据范围,要在边界范围内
链表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
1:单链表的优点不要连续空间,改变容量方便,不可以随机存储,耗费一定空间指针
2:强调这是一个单链表用Linklist
强调这是一个节点用LNode*
#### 总结:几次运行失败的原因,
#### 1:没有理解线性表的结构
#### 2:没有理解里面参数的实际意义如*,&
#### 3:运行使用的数据范围,要在边界范围内
# 链表
1:单链表的优点不要连续空间,改变容量方便,不可以随机存储,耗费一定空间指针
2:强调这是一个单链表用Linklist
强调这是一个节点用LNode*
3:带头节点,不带头节点[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传