文章目录
2.1抽象运算(算法2.1)
2.2顺序表存储的C语言实现创建一个空的顺序表(算法2.3)用类C语言实现顺序表的插入删除按值查找(顺序查找)
2.32.3.1.单链表单链表的C语言实现用类C语言实现单链表上的查询(查找第i个元素):单链表上的插入运算(第i个元素位置上插入新的结点)单链表上的删除运算(把第i个元素删除)用类C语言实现表头插入算法:用类C语言实现两个有序单链表的合并
2.3.2.循环单链表和双向链表双向链表的C语言描述
2.1
抽象运算(算法2.1)
例2-1 利用两个线性表LA和LB分别表示集合A和B,求一个新的集合A=A∪B。
算法思路:集合中的元素间是松散的关系,只需将在线性表LB中而不在LA中的数据元素追加到LA的尾部即可。
void union(List
&La
, List Lb
) {
La_len
= Length(La
);
Lb_len
= Length(Lb
);
for(i
= 1;i
<= Lb_len
; i
++) {
GetElem(Lb
, i
, e
);
if (!LocatElem(La
, e
, equal
))
InsertElem(La
, ++La_len
,e
);
}
}
2.2
顺序表存储的C语言实现
静态分配
#define MaxSize 100
typedef struct {
ElemType data
[MaxSize
];
int length
;
}SqList;
动态分配
#define InitSize 100
typedef struct {
ElemType
*data
;
int length
;
int MaxSize
;
}SqList;
L
.data
= (ElemTpye
*)malloc(sizeof(ElemType
)*InitSize
);
L
.data
= new ElemType
[InitSize
];
创建一个空的顺序表(算法2.3)
Status
InitList(SqList
&L
) {
L
.data
= (ElemTpye
*)malloc(sizeof(ElemType
)*InitSize
);
if (!L
.data
) exit(OVERFLOW
);
L
.length
= 0;
L
.MaxSize
= MAX_SIZE
;
return OK
;
}
用类C语言实现顺序表的插入
bool InsertList(SqList
&L
, int i
,ElemType e
)
{
if(i
< 1 || i
> L
.length
+ 1)
{
return false;
}
if(L
.length
>= MaxSize
)
{
return false;
}
for(int j
= L
.length
; j
>= i
; j
--)
{
L
.data
[j
] = L
.data
[j
-1];
}
L
.data
[i
-1] = e
;
L
.length
++;
return true;
}
Status
ListInsert_sq(SqList
&L
, int i
, ElemType x
)
{
if (i
< 1 || i
> L
.length
+ 1) return ERROR
;
if (L
.length
>= L
.Listsize
)
{
newbase
= (ElemType
*)realloc(L
.elem
, (L
.listsize
+ LISTINCREMENT
) * sizeof(ElemType
));
if (!newbase
) exit(OVERFLOW
);
L
.elem
= newbase
;
L
.listsize
+= INCREMENT
;
}
q
= &(L
.elem
[i
- 1]);
for (p
= &(L
.elem
[L
.length
- 1]); p
>= q
; --p
)
{
*(p
+ 1) = *p
;
}
*q
= x
;
L
.length
++;
return OK
;
}
删除
bool ListDelete(SqList
&L
, int i
, ElemType
&e
)
{
if(i
< 1 || i
> L
.length
)
{
return false;
}
e
= L
.data
[i
-1];
for(int j
=i
; j
<L
.length
;j
++)
{
L
.data
[j
-1] = L
.data
[j
];
}
L
.length
--;
return true;
}
按值查找(顺序查找)
int LocateELem(SqList L
, ElemType e
)
{
for(int i
= 0; i
< L
.length
; i
++)
{
if(L
.data
[i
] == e
) return i
+1;
}
return 0;
}
2.3
2.3.1.单链表
单链表的C语言实现
typedef struct LNode
{
ElemType data
;
struct LNode
*next
;
} LNode
, *LinkList
;
用类C语言实现单链表上的查询(查找第i个元素):
Status
GetElem_L(LinkList L
, int i
, ElemType
&e
)
{
p
= L
->next
;
k
= 1;
while (p
&& k
< i
)
{
p
= p
->next
;
++k
;
}
if (!p
|| k
> i
) return ERROR
;
e
= p
->data
;
return OK
;
}
查找第[1,n]个元素处,p对应第[1,n]个元素
思考: “本算法为何没有考虑 i值的合法性?” 两种非法:i<1和 i>n
i<1(i<=0):因为while的循环条件k < i,此时k>i,非法情况直接排除。i>n:p空了。
单链表上的插入运算(第i个元素位置上插入新的结点)
Status
ListInsert_L(LinkList
&L
, int i
, ElemType e
)
{
p
= L
;
k
= 0;
while (p
&& k
< i
- 1)
{
p
= p
->next
;
++k
;
}
if (!p
|| k
> i
- 1) return ERROR
;
if (!(s
= (LinkLinst
)malloc(sizeof(LNode
))))
return OVERFLOW
;
s
->data
= e
;
s
->next
= p
->next
;
p
->next
= s
;
return OK
;
}
合法区间:插入到第[1,n+1]个元素处,p对应第[0,n]个元素。
i<1:失败。i>n+1:失败。
单链表上的删除运算(把第i个元素删除)
Status
ListDelete_L(LinkList
&L
, int i
, ElemType
&e
)
{
p
= L
;
k
= 0;
while (p
->next
&& k
< i
- 1)
{
p
= p
->next
;
++k
;
}
if (!p
->next
|| k
> i
- 1) return ERROR
;
q
= p
->next
;
p
->next
= q
->next
;
e
= q
->data
;
free(q
);
return OK
;
}
思考: while语句中的p->next 可否用p替代? 不行,因为要保证p的下一个结点不能空。
合法区间:第[1,n]个元素,p对应第[0,n-1]个元素
用类C语言实现表头插入算法:
void CreateList_L(LinkLinst
&L
, int n
)
{
L
= (LinkList
)malloc(sizeof(LNode
));
L
->next
= NULL;
for (i
= n
; i
> 0; --i
)
{
p
= (LinkList
)malloc(sizeof(LNode
));
scanf(&p
->data
);
p
->next
= L
->next
;
L
->next
= p
;
}
}
用C语言实现表头插入算法:
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType
;
typedef struct LNode
{
ElemType data
;
struct LNode
*next
;
} LNode
, *LinkList
;
void ListDelete_L(LinkList
&L
, int n
)
{
L
= (LinkList
)malloc(sizeof(LNode
));
L
->next
= NULL;
LinkList p
= NULL;
for (int i
= n
; i
> 0; --i
)
{
p
= (LinkList
)malloc(sizeof(LNode
));
scanf("% d", &p
->data
);
p
->next
= L
->next
;
L
->next
= p
;
}
}
用类C语言实现两个有序单链表的合并
void MergeList_L(LinkList
&La
, LinkList
&Lb
, LinkList
&Lc
)
{
pa
= La
->next
;
pb
= Lb
->next
;
Lc
= (LinkList
)malloc(sizeof(LNode
));
Lc
->next
= NULL;
pc
= Lc
;
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
;
}
2.3.2.循环单链表和双向链表
双向链表的C语言描述
typedef struct DuLNode
{
ElemType data
;
struct DuLNode
*prior
;
struct DuLNode
*next
;
} DuLNode
, *DulinkList
;