利用C创建顺序表并进行增删改和合并。
最近在学习数据结构,做了一下第二章的一些算法,作为小白记录一下。
#include <stdio.h>
#include <stdlib.h>
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define OVERFLOW -2
#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;
typedef struct {
ElemType *elem;
int length;
int listsize;
}SqList;
Status InitList_Sq(SqList *L){
L->elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
if (!L->elem) exit(OVERFLOW);
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return OK;
} //创建一个空的线性表L。
ElemType GetListElem(SqList const *L, int const i){
ElemType *e;
if (i < 1 || i > L->length)
return ERROR;
else
e = L->elem +i -1;
return *e;
}
Status ListInsert_Sq(SqList *L, int const i, ElemType const e){
if (i < 1 || i > L->length + 1) return ERROR;
if(L->length >= L->listsize){
int *newbase;
newbase = (ElemType*)realloc(L->elem,
(L->listsize + LISTINCREMENT) * sizeof(ElemType));
if (!newbase)exit(OVERFLOW);
L->elem = newbase;
L->listsize += LISTINCREMENT;
}
ElemType *q = &(L->elem[i-1]); //q为插入的位置
for (int *p = &(L->elem[L->length-1]);p >=q; --p)
*(p + 1) = *p; //将元素后移一位
*q = e;
++L->length;
return OK;
}
Status ListDelete_Sq(SqList* L, int i){
if (i < 1 || i > L->length)
return (ERROR);
ElemType *p = &(L->elem[i-1]); //p为删除元素的位置
ElemType *q ;
q = L->elem + L->length -1;
for(++p; p <= q; ++p)
*(p-1) = *p;
--L->length;
return OK;
}
Status MergeList(SqList *La, SqList *Lb, SqList *Lc){
InitList_Sq(Lc);
ElemType i= 1;ElemType j =1; ElemType k = 0;
ElemType La_len = La->length;
ElemType Lb_len = Lb->length;
while ((i <= La_len) && (j <= Lb_len)){
ElemType ai; ElemType bj;
ai = GetListElem(La, i);
bj = GetListElem(Lb, j);
if(ai <= bj){
ListInsert_Sq(Lc, ++k, ai);
++i;}
else{
ListInsert_Sq(Lc, ++k, bj);
++j;
}
}
while (i <= La_len){
ElemType ai;
ai = GetListElem(La, i++);
ListInsert_Sq(Lc, ++k, ai);
}
while (j <= Lb_len){
ElemType bj;
bj = GetListElem(Lb, j++);
ListInsert_Sq(Lc, ++k, bj);
}
return OK;
}
Status PrintList(SqList *L){
for (int i = 0;i < L->length ;i++) {
printf("%d ",L->elem[i]);
}
return OK;
}
int main() {
SqList la;
SqList lb;
SqList lc;
InitList_Sq(&la);
InitList_Sq(&lb);
InitList_Sq(&lc);
ListInsert_Sq(&la,1,1);ListInsert_Sq(&la,2,3);ListInsert_Sq(&la,3,5);ListInsert_Sq(&la,4,7);
ListInsert_Sq(&lb,1,2);ListInsert_Sq(&lb,2,4);ListInsert_Sq(&lb,3,6);ListInsert_Sq(&lb,4,8);ListInsert_Sq(&lb,5,10);
//ListDelete_Sq(&la, 1);
int a = GetListElem(&la, 1);
MergeList(&la,&lb,&lc);
PrintList(&lc);
return 0;
}
有几点在做的时候的问题:
1.其实在书上并没有关于对Status、Elem声明的解释,即
typedef int Status
在网上搜了一下,这句是个自定义类型的语句。typedef用来定义类型的别名。
status i;就相当于int i;
至于为什么叫status,原因可能为status的英文意思是状态,编程者想用int值表示一个状态,所以自定义一个类型。这样status i;一看就知道变量i表示一个状态变量。而int i;就不能传达给读者这样一个意思。但是本质上是一样的,这样写就是为了传达编程的信息,方便以后维护,和读程序。
2.我用的书是清华大学出版社的数据结构(C语言版),书中的代码大多是伪代码,需要自己去定义函数,而对于书中诸如
void MergeList(List ls, List Lb, List &Lc)
这样的定义,老师的解释是加了“&”的数组是前后发生改变的形参,但好像这个只是在看书时方便理解,我在真正编码时还是采用加指针的形式,下次上课问问老师吧。
3.一开始不太理解为什么在定义elem时要加指针,因为L.elem指的是L的基地址,而指针变量的作用为指示地址。