代码参考了严版数据结构,仅用于个人的知识整理。
线性表:
顺序储存(随机存取)的线性表一般称为顺序表
定义顺序表:
typedef struct
{
int em1;
int em2;
}ElemType;
typedef struct
{
ElemType* elem; //储存顺序表的储存空间的第一个元素的地址 类似数组a[10] 中的a
int length; //储存顺序表的长度
}Sqlist;
初始化:需要注意,当空间分配失败时,返回0,成功返回1.
1.定义一个顺序表
2.给顺序表的分配一个空间,并用elem指针指向空间
3.将表长设为0
int InitList(Sqlist& L)
{
L.elem = new ElemType[MaxSize];
if (!L.elem) return 0 ;
L.length = 0;
return 1;
}
取值:获取指定位置i的值
1.判断位置是否合理,不合理返回0
2.若合理则将下标为i-1的值给e(e用于接收数据)
int GetElem(Sqlist L, int i, ElemType& e)
{
if(i<1||i>L.length) return 0
else {
e = L.elem[i - 1];
return 1;
}
}
查找:已知数据e,要在顺序表中找到其所在位置
1.找不到返回0,找到返回i+1
int LocationElem(Sqlist L, ElemType e)
{
for (int i = 0; i < L.length; i++)
{
if (e == L.elem[i]) return i + 1;
}
return 0;
}
插入:在顺序表的i位置插入一个新的数据
1.首先将i和其之后的数据全部向后移动一个单位,然后给i位置赋值
2.注意插入的范围,只能在1到L.length+1之间 i==L.length+1 时,不需要移动,而i==L.length 需要将最后一个移动
3.表满了,就不能插入
int ListInsert(Sqlist L, int i, ElemType e)
{
if(i<1 || i>L.length+1) return 0;
if (L.length == MaxSize) return 0;
for (int j = L.length-1; j>=i-1; j--)
{
L.elem[j + 1] = L.elem[j];
}
L.elem[i - 1] = e;
L.length++;
return 1;
}
删除:
1.如果表长为0,返回0
2.删除的范围只能在1到L.length之间<超过该区间返回0
int ListDelete(Sqlist L, int i)
{
if (L.length == 0) return 0;
if (i<1 || i>L.length) return 0;
for (int j = i; j < L.length; j++)
{
L.elem[j-1] = L.elem[j ];//相当于覆盖掉i-1位置的数
}
L.length--;
return 1;
}
单链表:
元素之间的逻辑关系由结点的指针指示:这种储存结构为非顺序映像或链式映像
为了方便讨论链表,引出几个概念:
首元结点:链表真正意义上的第一个元素
头结点:在首元结点之前设置的结点,指针域指向首元结点,其数据域一般不储存数据,也可用于储存该表的相关信息
头指针:有头结点就指向头结点
增加头节点可以方便首元节点的操作,无需对其特殊处理
判断链表是否为空:
1.无头结点,L==NULL为空
2.有头结点,L->next==NULL
初始化:
1.生成结点作为头结点,头指针指向头结点
2.头结点的指针域置空
struct ElemType
{
int a;
};
typedef struct LNode
{
ElemTye data; //数据
struct LNode* next;//指向下一级的指针
}LNode, * LinkList;
int InitList(LinkList& L)
{
L = new LNode; //生成一个头结点
L->next = NULL;
return 1;
}
取值:从首元结点出发,遍历
1.i的取值只能是1到n,超过这个范围出错
int GetElem(LinkList L, int i, ElemType & e)
{
LinkList p = L->next;
int j = 1;
while (p && j < i)
{
p = p->next;
j++;
}
if (!p || j > i) return 0; //i值不合法i>n 这时候p=NULL 或i<=0 j>i
e = p->data;
return 1;
}
查找:从首元结点出发,遍历
1.找到相等就返回
LNode* LocateElem(LinkList L, ElemType e)
{
LNode* p = L->next;
while (p && e != p->data)
{
p = p->next;
}
return p;
}
插入:将值为e的新结点插入表中第i个位置
1.生成一个结点s,设置数据域为e,设置它的指针域指向ai,ai-1的指针域指向s
int ListInsert(LinkList& L, int i, ElemType e)
{
LNode* p = L->next;
int j = 1;
while (p && j < i - 1)
{
p = p->next;
j++;
}
if (!p || j > i - 1) return 0;
LinkList s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return 1;
}
删除:将第i个位置的结点删除
1.找到i结点的上方,i-1
void DestoryList(LinkList& L, int i)
{
LinkList p = L->next;
int j = 1;
while (p && j < i-1)
{
p = p->next;
j++;
}
if (!p || j > i-1) return ; //i-1值不合法i-1>n 这时候p=NULL 或i-1<=0 j>i-1
//找到需要删除的结点的上一个
LinkList m=p->next;
p->next=p->next->next;
free(m);//将其释放
}
单链表的创建:
1.前插法
2.尾插法
void CreateList_H(LinkList& L, int n)
{
//头插
L = new LNode;
L->next = NULL;//建立头结点
while (n > 0)
{
LinkList p = new LNode;
cin >> p->data;
p->next = L->next;
L->next = p;
n--;
}
//尾插
LinkList r = L;
while (n > 0)
{
LinkList p = new LNode;
cin >> p->data;
r->next = p;
r = p;
n--;
}
}
// 头结点 1 2 3 4 5
单链表的逆转:
void Listreserve(LinkList& L,int n)
{
LinkList now, old, tem;
now = L->next;
old = L->next;
tem = L->next->next;
while (n - 1 > 0)
{
now = tem;
tem = now->next;
now->next = old;
old = now;
n--;
}
L->next->next = tem;
L->next = now;
}
链表的数据域涉及比较的时候不能像上述代码那么简单,这样是会报错的,要将数据域的结构体中的成员一个一个比较。
代码如果有遗漏的地方,欢迎各位大佬指出!