线性表的相关算法总结

顺序表的操作

更多内容请看https://blog.csdn.net/weixin_43790779

1. 顺序表的存储结构定义

1
2
3
4
5
6
7
8
#define MAXSIZE 100
typedef int ElemType;

typedef struct
{
ElemType *elem; //存储空间基址
int length; //表长
}SqList;

2. 初始化顺序表

1
2
3
4
5
6
7
8
void InitList_Sq(SqList &L)
{
//构造一个空的顺序表L。
L.elem = new ElemType[MAXSIZE];
if(!L.elem)
exit(OVERFLOW); // 存储分配失败
L.length = 0; // 空表长度为0
}

3. 销毁顺序表

1
2
3
4
5
6
7
void DestroyList(SqList &L)
{
if(L.elem)
delete(L.elem); //释放存储空间
L.length = 0;
L.elem = NULL;
}

4. 清空顺序表

1
2
3
4
void ClearList(SqList &L)
{
L.length = 0; //将线性表的长度置为0
}

5. 求顺序表的长度

1
2
3
4
int GetLength(SqList L)
{
return L.length;
}

6. 判断顺序表是否为空

1
2
3
4
5
6
7
bool IsEmpty(SqList L)
{
if(L.length == 0)
return true;
else
return false;
}

7. 获取顺序表中的某个位置数据元素内容

时间复杂度为O(1)

1
2
3
4
5
6
void GetElem(SqList L,int i,ElemType &e)
{
if(i<1 || i>L.length) //判断i值是否合理,若不合理,返回ERROR
return ERROR;
e = L.elem[i-1]; //i是元素在表中的位置
}

8. 在顺序表中查找值为e的数据元素

时间复杂度为O(n)

1
2
3
4
5
6
7
int LocateElem(SqList L,ElemType e)
{
for(int i=0;i<L.length;i++)
if(L.elem[i] == e)
return i+1; //i是存储单元的位置
return 0;
}

9. 在顺序表中插入一个数据元素

时间复杂度为O(n)

1
2
3
4
5
6
7
8
9
10
11
void ListInsert_Sq(SqList &L,int i,ElemType e)
{
if(i<1 || i>L.length+1) //判断插入位置是否合法
return ERROR;
if(L.length == MAXSIZE) //当前存储空间是否已满
return ERROR;
for(int j = L.length-1;j>=i-1;j--) //将元素后移
L.elem[j+1] = L.elem[j];
L.elem[i-1] = e;
++L.length;
}

10. 删除顺序表中的第i个数据元素

时间复杂度为O(n)

1
2
3
4
5
6
7
8
void ListDelete_Sq(SqList &L,int i)
{
if(i<1 || i>L.length) //判断插入位置是否合法
return ERROR;
for(int j=i-1;j<L.length;j++) //将元素前移
L.elem[j] = L.elem[j+1];
--L.lehgth;
}

链表的操作

1. 单链表的存储结构定义

1
2
3
4
5
typedef struct LNode
{
ElemType data; //数据域
struct LNnode *next; //指针域
}LNode,*LinkList; //LinkList为LNode类型的指针

2. 初始化单链表

1
2
3
4
5
void InitList_L(LinkList &L)
{
L = new LNode;
L->next = NULL;
}

3. 销毁单链表

1
2
3
4
5
6
7
8
9
10
void DestroyList_L(LinkList &L)
{
LinkList p;
while(p)
{
p = L;
L = L->next;
delete p;
}
}

4. 清空单链表

1
2
3
4
5
6
7
8
9
10
11
12
void ClearList(LinkList &L)
{
LinkList p,q;
p = L->next;
while(p) //没到表尾
{
q = p->next; //p指向第一个结点
delete p;
p = q;
}
L->next = NULL; //头结点指针域为空
}

5. 求单链表的长度

1
2
3
4
5
6
7
8
9
10
11
12
13
int ListLength_L(LinkList L)
{
LinkList p;
p = L->next;
count = 0;
//遍历单链表,统计结点数
while(p)
{
++count;
p = p->next;
}
return count;
}

6. 判断单链表是否为空

1
2
3
4
5
6
7
bool ListEmpty(LinkList L)
{
if(L->next)
return true;
else
return false;
}

7. 获取单链表中的某个数据元素内容

时间复杂度为O(n)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//获取第i个位置的元素
void GetElem_L(LinkList L,int i,ElemType &e)
{
LinkList p = L->next;
int j = 1;
//向后扫描,直到p指向第i个元素或p为空
while(p && j<i)
{
p = p->next;
++j;
}
if(!p || j>i) //第i个元素不存在
return ERROR;
e = p->data; //取第i个元素
}

8. 检索值为e的数据元素

1
2
3
4
5
6
7
8
LNode *LocateElem_L(LinkList L,ElemType e)
{
p = L->next;
while(p && p->data != e)
p = p->next;
//返回L中值为e的数据元素的位置,查找失败返回NULL
return p;
}

9. 在单链表中插入一个数据元素

时间复杂度为O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void ListInsert_L(LinkList L,int i,ElemType e)
{
p = L;
j = 0;
//寻找第i−1个结点
while(p && j<i-1)
{
p = p->next;
++j;
}
//i大于表长 + 1或者小于1
if(!p || j>i-1)
return ERROR;
//生成新结点*s
s = new LNode;
s->data = e; //将结点*s的数据域置为e
s->next = p->next; //将结点*s插入L中
p->next = s;
}

10. 删除单链表中第i个数据

时间复杂度为O(1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ListDelete_L(LinkList L,int i,ElemType &e)
{
p = L;
j = 0;
//寻找第i个结点,并令p指向其前驱
while(p->next && j<i-1)
{
p = p->next;
++j;
}
//删除位置不合理
if(!p->next || j>i-1)
return ERROR;
//临时保存被删结点的地址以备释放
r = p->next;
//改变删除结点前驱结点的指针域
p->next = r->next;
e = r->data;
//释放结点
delete r;
}

11. 单链表的建立

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
27
28
29
//前插法
void CreateList_H(LinkList &L,int n)
{
L = new LNode;
L->next = NULL; //先建立一个带头结点的单链表
for(int i=n;i>0;i--)
{
p = new LNode; //生成新结点
cin >> p->data;
p->next = L->next;
L->next = p; //插入到表头
}
}
//后插法
//正位序输入n个元素的值,建立带表头结点的单链表L
void GreateList_R(LinkList &L,int n)
{
L = new LNode;
L->next = NULL;
r = L; //尾指针r指向头结点
for(int i=0;i<n;i++)
{
p = new LNode; //生成新结点
cin >> p->data;
p->next = NULL;
r->next = p; //插入到表尾
r = p; //r指向新的尾结点
}
}

线性表的应用

1. 线性表的合并

1
2
3
4
5
6
7
8
9
10
11
12
void union(List &La,List &Lb)
{
La_len = ListLength(La); //线性表La的长度
Lb_len = ListLength(Lb); //线性表Lb的长度
for(int i=1;i<=La_length;i++)
{
GetElem(Lb,i,e); // 取Lb中第i个数据元素赋给e
// La中不存在和 e 相同的数据元素,则插入之
if(!LocateElem(La,e))
ListInsert(La,++La_len,e);
}
}

2. 链式有序表的合并

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
27
28
//按值排序的单链表LA,LB,归并为LC后也按值排序
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
//初始化
pa = La->next;
pb = Lb->next;
Lc = pc = La;
//将pa 、pb结点按大小依次插入C中
while(pa && pb)
{
if(pa->data <= pb->data)
{
pc->next = pa;
pc = pa;
pa = pa->next;
}
else
{
pc->next = pb;
pc = pb;
pb = pb->next;
}
}
//插入剩余段
pc->next = pa?pa:pb;
//释放Lb的头结点
delete pb;
}

3. 顺序有序表的合并

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
27
28
29
30
31
32
33
void MergeList(List La,List Lb,List &Lc)
{
InitList(Lc);
i = j = 1;
k = 0;
La_len = ListLength(La);
La_len = ListLength(La);
while(i<=La_len)&&(j<=Lb_len)
{
GetElem(La,i,ai);
GetElem(Lb,j,bj);
if (ai<=bj)
{
ListInsert(Lc,++k,ai);
++i;
}
else
{
ListInsert(Lc,++k,bj);
++j;
}
}
while (i<=La_len)
{
GetElem(La,i++,ai);
ListInsert(Lc,++k,ai);
}
while (j<=Lb_len)
{
GetElem(Lb,j++,bj);
ListInsert(Lc,++k,bj);
}
}
坚持原创技术分享,您的支持将鼓励我继续创作!