链接表示是实现线性表的另一种经常使用的存储结构,这种存储结构不要求逻辑上相邻的两个元素在
物理位置上也相邻存储,而是通过增加元素指针来指示元素之间的逻辑关系和后继元素的位置。
线性表的链接表示就是用一组可以不连续的存储单元,存储线性表的各个元素,为了表示其后继与其的逻辑关系,每个元素除了需要存储自身的信息外,还要存储一个只是其后继的信息(即后继元素的存储位置)。这样每个元素(结点)就包括两个域:数据域和指针域,由于最后一个元素没有后继,他的指针不指向任何结点这称为空指针复制为NULL。
假设一个线性表有n个元素。则这n个元素就对应n个结点就通过指针链接成一个链表,在链表中每一个结点只有一个指向其后继的指针域,这中链表称之为单链表,指向链表中第一个几结点的指针,称为链表的头指针。所以定义一个单链表就可以这样:
struct Node; //用结点Node表示单链表元素更形象
typedef struct Node *pNode;
struct Node {
int info; //data scope
pNode link; //pointer scope point the next link
};
typedef struct Node *LinkList; //用Link]List表示单链表为了和结点区别开来对阅读程序有好处
对单链表的基本操作有:创建单链表,插入结点,删除结点,定位结点位置等等。与顺序表一样先创建一个单链表:
LinkList creatNullLinkList () { LinkList llist; llist = (LinkList) malloc (sizeof (struct Node)); if (NULL == llist) { printf ("memory allocation error!\n"); //创建失败 return NULL; } llist->link = NULL; //创建完成,只有一个头结点指向空指针 return llist; //返回单链表 }
插入单链表:在结点位置前插入
void inertPreLinkList (LinkList llist,pNode pos,int x) { LinkList p = (LinkList) malloc (sizeof (struct Node)); if (p == NULL){ printf ("insert error!memory error!\n"); //失败 } p->info = x; p->link = pos->link; pos->link = p;//插入 }
在P结点位置后插入:void inertPostLinkList (LinkList llist,pNode pos,int x) { LinkList p = (LinkList) malloc (sizeof (struct Node)); if (p == NULL){ printf ("insert error!memory error!\n"); //失败 } p->info = x; p->link = pos->link; pos->link = p; //插入 }
在单链表中P所指的前驱结点:
pNode locatPreNode (LinkList llist,pNode p) { pNode node; if (NULL == llist) { printf ("location error,Null list!\n"); return NULL; //失败 } node = llist; while (node != NULL && node->link != p) node = node->link; return node; //返回 }
删除结点:
void deletNodeLinkList (LinkList llist,pNode p) { pNode q; q = locatPreNode (llist,p); if (q->link == NULL) { printf ("delet error,list null!\n");//失败 } else{ q->link = p->link; free (p); //删除 } }
单链表和顺序表都是非常重要的线性存储结构,许多数据结构都可以由它实现,掌握好顺序表和单链表非常重要