一,双链表
即相对于单链表,双链表多了一个前驱指针,以用来指向其前驱结点。
双链表的初始化以及判断是否为空
typedef struct DNode { //定义双链表结点类型
int data; //数据域
struct DNode* prior, * next; //前驱指针和后驱指针。
}DNode,*DLinkList;
//初始化双链表
bool InitDLinkList(DLinkList& L) {
L = (DLinkList)malloc(sizeof(DNode));
if (L == NULL) { //内存不足,分配失败
return;
}
L->prior = NULL; //头结点prior永远指向null
L->next = NULL; //头结点之后暂时还没有后结点
return true;
}
void testDLinkList() {
//初始化双链表
DLinkList L;
InitDLinkList(L);
}
//判断双链表是否为空
bool Empty(DLinkList L) {
if (L->next == NULL) {
return true;
}else{
return false;
}
}
指定结点的后插操作
在结点P后面插入S结点
步骤:将P结点的后驱指针(p.next)赋值给s.next。将s的前驱指针(s.prior)指向p。
然后再将p结点的原后驱结点的前驱指针指向s,p的后驱指针指向s即可
//在结点P后面插入S结点
bool InserNextDNode(DNode *p, DNode *s) {
if (p == NULL || s == NULL) {
return false;
}
s->next = p->next;
if (p->next != NULL) {
s->prior = p;
p->next->prior = s;
p->next = s;
return true;
}
else {
p->next = s;
s->prior = p;
}
}
删除指定结点的后结点
//删除p结点的后继结点.
bool DeleteDNode(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 = p;
}
free(q);
return true;
}
销毁双链表
//销毁一个双链表
void DestoryList(DLinkList& L) {
while (L->next != NULL)
{
DeleteDNode(L);
}
free(L);
L = NULL;
}
二,循环链表
1,循环单链表
即相对于单链表,单链表的最后一个结点的后驱指针指向的是null,而循环链表的最后一个结点的后驱指针指向的是头结点
循环单链表的特点,只需要知道其中任意一个结点,就能找到链表中所有结点
2,循环双链表
相比于浦东的双链表,循环双链表的头结点的prior指向表尾结点,表尾结点的next指向头结点。
//初始化双链表
bool InitDLinkList(DLinkList& L) {
L = (DLinkList)malloc(sizeof(DNode));
if (L == NULL) { //内存不足,分配失败
return false;
}
L->prior = L; //头结点prior永远指向null
L->next = L; //头结点之后暂时还没有后结点
return true;
}
void testDLinkList() {
//初始化双链表
DLinkList L;
InitDLinkList(L);
}
//判断循环双链表是否为空
bool Empty(DLinkList L) {
if (L->next = L) {
return true;
}
else {
return false;
}
}
//判断结点p是否是其尾结点
bool isTail(DLinkList L,DNode *p) {
if (p->next == L) {
return true;
}
else {
return false;
}
}
//在p结点后插入结点s
bool InserNexDNode(DNode *p, DNode *s) {
s->next = p->next;
s->prior = p;
p->next->prior = s;
p->next = s;
return true;
}
静态链表
相比于单链表的各个结点在内存中是随机存放的,静态链表在内存是一整块连续的内存空间,各个结点集中安放。
各个结点中有指向下一个数组下标的游标(类似指针),最后一个结点的游标为-1(表示在它后面没有结点了)。
假设每个数据元素大小为4B,每个游标为4B(即每个结点大小为8B)设起始地址为addr
则 e1的存放地址为addr+8*2(2为数组下标)