- 顺序表基本操作
//顺序表的存储结构
#define MAXSIZE 100
typedef struct{
ElemType *elem; //存储空间的基地址
int length; //当前长度
}SqList; //顺序表的结构类型为SqList
//顺序表的初始化:构造一个空的顺序表L
Status InitList(SqList &L){
L.elem = new ElemType[MAXSIZE]; //为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem) exit(OVERFLOW); //存储分配失败退出
L.length = 0; //空表长度为0
return OK;
}
//顺序表的取值
Status GetItem(SqList L, int i, ElemType &e){
if(i < 1 || i > L.length) return ERROR; //判断i值是否合理,若不合理返回ERROR
e = L.elem[i-1]; //elem[i-1]单元存储第i个数据
return OK;
}
//顺序表的查找:在顺序表L中查找值为e的元素,返回其序号
int LocateElem(SqList L, ElemType e){
for(i = 0; i < L.length; i++){
if(L.elem[i] == e) return i + 1; //查找成功,返回序号i+1
}
return 0; //查找失败,返回0
}
//顺序表的插入:在顺序表L中第i个位置之前插入新的元素e
Status ListInsert(SqList &L, int i, ElemType e){
if((i < 1) || (i > L.length + 1)) return ERROR; //i值不合法
if(L.length == MAXSIZE) return ERROR; //当前存储空间已满
for(j = L.length - 1; j >= i - 1; j--){
L.elem[j + 1] = L.elem[j]; //插入位置及之后的元素后移
}
L.elem[i - 1] = e; //将新元素e放入第i个位置
++L.length; //表长加1
return OK;
}
//顺序表的删除:在顺序表L中删除第i个元素
Status ListDelete(SqList &L, int i){
if((i < 1) || (i > L.length)) return ERROR; //i值不合法
for(j = 1; j < L.length - 1; j++){
L.elem[j - 1] = L.elem[j]; //被删除元素之后的元素前移
}
--L.length; //表长减1
return OK;
}
- 单链表基本操作
//单链表的存储结构
typedef struct LNode{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode, *LinkList; //LinkList为指向结构体LNode的指针类型
//单链表的初始化:构造一个空的单链表L
Status InitList(LinkList &L){
L = new LNode; //生成新结点作为头结点,用指针L指向头结点
L->next = NULL; //头结点的指针域置空
return OK;
}
//单链表的取值:在带头结点的单链表L中根据序号i获取元素的值,用e返回L中第i个元素的值
Status GetItem(LinkList L, int i, ElemType &e){
p = L->next; //初始化,p指向首元结点
j = 1; //计数器的初值赋为1
while(p && j < i){ //顺链域向后扫描,知道p为空或p指向第i个元素
p = p->next; //p指向下一个结点
++j; //计数器j相应加1
}
if(!p || j > i) return ERROR; //i值不合法i>n或i<=0
e = p->data; //取第i个结点的数据域
return OK;
}
//单链表的按值查找:在带头结点的单链表中查找值为e的元素
LNode *LocateElem(LinkList L, ElemType e){
p = L->next; //初始化,p指向首元结点
while(p && p->data != e) //顺链域向后扫描,直到p为空或p所指结点的数据域等于e
p = p->next; //p指向下一结点
return p; //查找成功返回值为e的结点地址p,查找失败p为NULL
}
//单链表的插入:在带头结点的单链表L中第i个位置插入值为e的新结点
Status ListInsert(LinkList &L, int i, ElemType e){
p = L;
j = 0;
while(p && (j < i - 1)){ //查找第i个结点,p指向该结点
p = p->next;
++j;
}
if(!p || j > i - 1) return ERROR; //i>n+1或者i<n+1
s = new LNode; //生成新结点*s
s->data = e; //将结点*s的数据域置为e
s->next = p->next; //将结点*s的指针域指向结点a_i
p->next = s; //将结点*p的指针域指向结点*s
return OK;
}
//单链表的删除:在带头结点的单链表L中,删除第i个元素
Status ListDelete(LinkList &L, int i){
p = L;
j = 0;
while((p->next) && (j < i - 1)){//查找第i个结点,p指向该结点
p = p->next;
++j;
}
if(!(p->next) || (j > i - 1)) //当i>n或i<1时,删除位置不合理
return ERROR;
q = p->next; //临时保存被删结点的地址以备释放
p->next = q->next; //改变删除结点前驱结点的指针域
delete q; //释放删除结点的空间
return OK;
}
//前插法创建单链表:逆位序输入n个元素的值,建立带头结点的单链表L
void CreateList_H(LinkList &L, int n){
L = new LNode;
L->next = NULL; //先建立一个带头结点的空链表
for(i = 0; i < n; ++i){
p = new LNode; //生成新结点*p
cin >> p->data; //输入元素值赋给新结点*p的数据域
p->next = L->next;
L->next = p; //将新结点*p插入到头结点之后
}
}
//后插法创建单链表:正位序输入n个元素的值,建立带表头结点的单链表L
void CreateList_R(LinkList &L, int n){
L = new LNode;
L->next = NULL; //先建立一个带头结点的空链表
r = L; //尾指针r指向头结点
for(i = 0; i < n; ++i){
p = new LNode; //生成新结点
cin >> p->data; //输入元素值赋给新结点*p的数据域
p->next = NULL;
r->next = p; //将新结点*p插入尾结点*r之后
r = p; //r指向新的尾结点*p
}
}
- 双向链表基本操作
typedef struct DuLNode{
ElemType data; //数据域
struct DuLNode *prior; //直接前驱
struct DnLNode *next; //直接后继
}DuLNode, *DuLinkList;
//双向链表的插入:在带头结点的双向链表L中第i个位置之前插入元素e
Status ListInsert_DuL(DuLinkList &L, int i, ElemType e){
if(!(p = GetElem_DuL(L, i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
s = new DuLNode; //生成新结点*s
s->data = e; //将结点*s数据域置为e
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s;
return OK;
}
//双向链表的删除:删除带头结点的双向链表L中的第i个元素
Status ListDelete_DuL(DuLinkList &L, int i){
if(!(p = GetElem_DuL(L, i))) //在L中确定第i个元素的位置指针p
return ERROR; //p为NULL时,第i个元素不存在
p->prior->next = p->next; //修改被删结点的前驱结点的后继指针
p->next->prior = p->prior; //修改被删结点的后继指针的前驱指针
delete p; //释放被删结点的空间
return OK;
}
参考资料:《数据结构(C语言版)(第2版)》 严蔚敏 李冬梅 吴伟民