2-2-1链表的基本操作(头结点与不带头结点的链表)
下面不带头结点的链表操作,与带头结点的链表操作,都用到同一个数据存储结构LinkListType.h
//LinkListType.h线性表的单链表存储结构
#pragma once
#ifndef __LINKLISTTYPE_H__
#define __LINKLISTTYPE_H__
typedef int ElemType;
struct LNode
{
ElemType data;
LNode *next;
};
typedef LNode *LinkNode; // 另一种定义LinkList的方法
#endif
*LinkNode和*next都是指向LNode类型的节点
不带头结点的LinkListBasicOperation.h
#pragma once
#ifndef _LINKLISTBASICOPERATION_H__
#define _LINKLISTBASICOPERATION_H__
#include "c1.h"
#include "LinkListType.h"
#define DestroyList ClearList // DestroyList()和ClearList()的操作是一样的
void InitList(LinkNode &L);
void ClearList(LinkNode &L);
Status ListEmpty(LinkNode L);
int ListLength(LinkNode L);
Status GetElem(LinkNode L,int pos,ElemType &e);
int LocateElem(LinkNode L,ElemType e,Status(*compare)(ElemType,ElemType));
Status PriorElem(LinkNode L,ElemType cur_e,ElemType &pre_e);
Status NextElem(LinkNode L,ElemType cur_e,ElemType &next_e);
Status ListInsert(LinkNode &L,int pos,ElemType e);
Status ListDelete(LinkNode &L,int pos,ElemType &e);
void ListTraverse(LinkNode L,void(*vi)(ElemType));
#endif
不带头结点的ListInsert和ListDelete都需要用到&L引用
带头结点的LinkListBasicOperationWithHead.h
#pragma once
#ifndef _LINKLISTBASICOPERATIONWITHHEAD_H__
#define _LINKLISTBASICOPERATIONWITHHEAD_H__
#include "c1.h"
#include "LinkListType.h"
void InitList(LinkNode &L);
void DestroyList(LinkNode &L);
void ClearList(LinkNode L);
Status ListEmpty(LinkNode L);
int ListLength(LinkNode L);
Status GetElem(LinkNode L,int i,ElemType &e);
int LocateElem(LinkNode L,ElemType e,Status(*compare)(ElemType,ElemType));
Status PriorElem(LinkNode L,ElemType cur_e,ElemType &pre_e);
Status NextElem(LinkNode L,ElemType cur_e,ElemType &next_e);
Status ListInsert(LinkNode L,int i,ElemType e);
Status ListDelete(LinkNode L,int i,ElemType &e);
void ListTraverse(LinkNode L,void(*vi)(ElemType));
#endif
带头结点的ListInsert和ListDelete则没有用到&L引用
下面透过对比12个操作来区分头结点和不带头结点的区别
1.初始化链表
//不带
void InitList(LinkNode &L)
{ // 操作结果:构造一个空的线性表L
L=NULL; // 指针为空
}
//带
void InitList(LinkNode &L)
{ // 操作结果:构造一个空的线性表L
L=(LinkNode)malloc(sizeof(LNode)); // 产生头结点,并使L指向此头结点
if(!L) // 存储分配失败
exit(OVERFLOW);
L->next=NULL; // 指针域为空
}
不带头结点{
初始化第一个节点的指针
}
带头结点{