数据结构学习:顺序表之双链表与循环链表
//定义双链表结点
typedef struct DNode
{
ElemType data; //数据域
struct DNode *prior,*next; //前指针和后指针
}DNode,*DLinkList; //其中DLinkList等价于DNode*
初始化双链表
//初始化双链表
bool InitDLinkList(DLinkList &L)
{
L = (DNode *)malloc(sizeof(DNode));//内存中分配一个结点为头结点
if(L == NULL)
return false; //内存分配失败
L->prior = NULL; //头结点的前驱为空
L->next = NULL; //初始化,后驱未添加为空
return true;
}
双链表的后插操作
//双链表的后插操作
bool InsertNextDNode(DNode *p,DNode *s)
{
if(p == NULL || s == NULL) //判断结点是否合法
return false;
s->next = p->next;
if(p->next != NULL) //p结点后继是否有结点
p->next->prior = s; //有的话把后继结点的前驱指向插入的结点
s->prior = s;
p->next = s;
//注意指针的修改顺序
return true;
}
删除双链表中结点p的后继结点
//删除双链表中结点p的后继结点
bool DeteleNextDNode(DNode *p)
{
if(p == NULL)
return false;
DNode *q = p->next; //定义一个指针指向结点p的后继结点
if(q == NULL) //如果后继结点为空
return false;
p->next = q->next;
if(q->next != NULL)
q->next->prior = q; //q的后继的前驱指向p结点
free(q); //释放结点q
return true;
}
销毁双链表
void DestoryList(DLinkList &L)
{
//使用循环删除各结点
while(L->next != NULL)
DeteleNextDNode(L);
free(L); //释放头指针空间
L = NULL; //头指针指向空
}
双链表的遍历
//向后遍历
while(p!=NULL)
p = p->next;
//向前遍历
while(p!=NULL)
p = p->prior;
//向前遍历
while(p->prior != NULL)
p = p->prior;
循环链表
循环单链表:
表尾结点的next指针指向头结点
循环双链表:
表头结点的 prior 指向表尾结点;表尾结点的 next 指向头结点
循环单链表
先定义一个单链表结点
struct LNode{ //定义单链表结点类型
ElemType data; //结点的数据域,用来存放数据
struct LNode *next;//指针域,存放指向下一个结点的指针
}LNode *LinkList;
初始化单链表
// 初始化单链表(带头结点)
bool IntiList(LinkList L)
{
L = (LNode *)malloc(sizeof(LNode));//分配一个头结点
if(L == NULL)
return false; //头结点分配失败
L->next = L; //头结点指向自己
return true;
}
循环双链表
//初始化双链表
bool InitDLinkList(DLinkList &L)
{
L = (DNode *)malloc(sizeof(DNode));//内存中分配一个结点为头结点
if(L == NULL)
return false; //内存分配失败
L->prior = L; //头结点的前驱为空
L->next = L; //初始化,后驱未添加为空
return true;
}
循环链表判断是否为空只需要判断是否指向自己即可
//循环链表判断是否为空只需要判断是否指向自己即可
bool Empty(LinkList L)
{
if(L->next == L)
return true;
else
return false;
}
//循环链表判断是否为尾结点只需要判断是否指向头结点即可
//循环链表判断是否为尾结点只需要判断是否指向头结点即可
bool isFail(LinkList L,LNode *p)
{
if(p->next == L)
return true;
else
return false;
}
循环双链表的插入
bool InsertNextDNode(DNode *p,DNode *s)
{
s->next = p->next;
p->next->prior = s; //有的话把后继结点的前驱指向插入的结点
s->prior = s;
p->next = s;
//注意指针的修改顺序
return true;
}